Merge "Revert "Fix PagedTileLayout reveal animation crash.""
diff --git a/Android.bp b/Android.bp
index 21b8404..6815a0d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -94,6 +94,7 @@
"core/java/android/app/trust/IStrongAuthTracker.aidl",
"core/java/android/app/trust/ITrustManager.aidl",
"core/java/android/app/trust/ITrustListener.aidl",
+ "core/java/android/app/backup/IBackupCallback.aidl",
"core/java/android/app/backup/IBackupManager.aidl",
"core/java/android/app/backup/IBackupObserver.aidl",
"core/java/android/app/backup/IBackupManagerMonitor.aidl",
diff --git a/Android.mk b/Android.mk
index f81f756..edbb94d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -171,15 +171,17 @@
-hidePackage com.android.server
# Convert an sdk level to a "since" argument.
-since-arg = -since $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(1)/public/api/android.*) $(1)
+since-arg = -since $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(1)/public/api/android.$(2)) $(1)
-finalized_sdks := $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.xml,%,\
- $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.xml))
-finalized_sdks += $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.txt,%,\
- $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.txt))
-finalized_sdks := $(call numerically_sort,$(finalized_sdks))
+finalized_xml_sdks := $(call numerically_sort,\
+ $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.xml,%,\
+ $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.xml)))
+finalized_txt_sdks := $(call numerically_sort,\
+ $(patsubst $(HISTORICAL_SDK_VERSIONS_ROOT)/%/public/api/android.txt,%,\
+ $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/*/public/api/android.txt)))
-framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_sdks),$(call since-arg,$(sdk)))
+framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_xml_sdks),$(call since-arg,$(sdk),xml))
+framework_docs_LOCAL_DROIDDOC_OPTIONS += $(foreach sdk,$(finalized_txt_sdks),$(call since-arg,$(sdk),txt))
ifneq ($(PLATFORM_VERSION_CODENAME),REL)
framework_docs_LOCAL_DROIDDOC_OPTIONS += \
-since ./frameworks/base/api/current.txt $(PLATFORM_VERSION_CODENAME)
@@ -361,8 +363,8 @@
LOCAL_SRC_GREYLIST := frameworks/base/config/hiddenapi-light-greylist.txt
LOCAL_SRC_VENDOR_LIST := frameworks/base/config/hiddenapi-vendor-list.txt
LOCAL_SRC_FORCE_BLACKLIST := frameworks/base/config/hiddenapi-force-blacklist.txt
-LOCAL_SRC_PUBLIC_API := $(INTERNAL_PLATFORM_DEX_API_FILE)
-LOCAL_SRC_PRIVATE_API := $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
+LOCAL_SRC_PUBLIC_API := $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST)
+LOCAL_SRC_PRIVATE_API := $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)
LOCAL_SRC_REMOVED_API := $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)
LOCAL_SRC_ALL := \
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index c74516d..2df7042 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -5,6 +5,7 @@
core/tests/coretests/src/android/
packages/PrintRecommendationService/
packages/PrintSpooler/
+ packages/PackageInstaller/
services/print/
services/usb/
telephony/
diff --git a/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java b/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
index 9fad19f..66a2600d 100644
--- a/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
+++ b/apct-tests/perftests/core/src/android/os/BinderCallsStatsPerfTest.java
@@ -48,7 +48,7 @@
@Before
public void setUp() {
- mBinderCallsStats = new BinderCallsStats(new Random());
+ mBinderCallsStats = new BinderCallsStats(new BinderCallsStats.Injector());
}
@After
@@ -58,25 +58,30 @@
@Test
public void timeCallSession() {
mBinderCallsStats.setDetailedTracking(true);
- final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
- Binder b = new Binder();
- int i = 0;
- while (state.keepRunning()) {
- CallSession s = mBinderCallsStats.callStarted(b, i % 100);
- mBinderCallsStats.callEnded(s, 0, 0);
- i++;
- }
+ runScenario();
+ }
+
+ @Test
+ public void timeCallSessionOnePercentSampling() {
+ mBinderCallsStats.setDetailedTracking(false);
+ mBinderCallsStats.setSamplingInterval(100);
+ runScenario();
}
@Test
public void timeCallSessionTrackingDisabled() {
mBinderCallsStats.setDetailedTracking(false);
+ runScenario();
+ }
+
+ private void runScenario() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
Binder b = new Binder();
while (state.keepRunning()) {
- CallSession s = mBinderCallsStats.callStarted(b, 0);
- mBinderCallsStats.callEnded(s, 0, 0);
+ for (int i = 0; i < 1000; i++) {
+ CallSession s = mBinderCallsStats.callStarted(b, i % 100);
+ mBinderCallsStats.callEnded(s, 0, 0);
+ }
}
}
-
}
diff --git a/api/current.txt b/api/current.txt
index 408e2b2..7f4fae5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -272,6 +272,7 @@
field public static final int allowBackup = 16843392; // 0x1010280
field public static final int allowClearUserData = 16842757; // 0x1010005
field public static final int allowEmbedded = 16843765; // 0x10103f5
+ field public static final int allowForceDark = 16844171; // 0x101058b
field public static final int allowParallelSyncs = 16843570; // 0x1010332
field public static final int allowSingleTap = 16843353; // 0x1010259
field public static final int allowTaskReparenting = 16843268; // 0x1010204
@@ -1294,6 +1295,7 @@
field public static final int summaryColumn = 16843426; // 0x10102a2
field public static final int summaryOff = 16843248; // 0x10101f0
field public static final int summaryOn = 16843247; // 0x10101ef
+ field public static final int supportsAmbientMode = 16844172; // 0x101058c
field public static final int supportsAssist = 16844016; // 0x10104f0
field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
field public static final int supportsLocalInteraction = 16844047; // 0x101050f
@@ -2818,6 +2820,7 @@
field public static final java.lang.String SERVICE_META_DATA = "android.accessibilityservice";
field public static final int SHOW_MODE_AUTO = 0; // 0x0
field public static final int SHOW_MODE_HIDDEN = 1; // 0x1
+ field public static final int SHOW_MODE_WITH_HARD_KEYBOARD = 2; // 0x2
}
public static abstract class AccessibilityService.GestureResultCallback {
@@ -6279,6 +6282,7 @@
method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager);
method public android.graphics.drawable.Drawable loadThumbnail(android.content.pm.PackageManager);
+ method public boolean supportsAmbientMode();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.WallpaperInfo> CREATOR;
}
@@ -12673,6 +12677,7 @@
method public static void appendColumns(java.lang.StringBuilder, java.lang.String[]);
method public void appendWhere(java.lang.CharSequence);
method public void appendWhereEscapeString(java.lang.String);
+ method public void appendWhereStandalone(java.lang.CharSequence);
method public java.lang.String buildQuery(java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
method public deprecated java.lang.String buildQuery(java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String);
method public static java.lang.String buildQueryString(boolean, java.lang.String, java.lang.String[], java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
@@ -15175,6 +15180,37 @@
package android.graphics.fonts {
+ public class Font {
+ method public android.graphics.fonts.FontVariationAxis[] getAxes();
+ method public int getTtcIndex();
+ method public int getWeight();
+ method public boolean isItalic();
+ field public static final int FONT_WEIGHT_BLACK = 900; // 0x384
+ field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+ field public static final int FONT_WEIGHT_EXTRA_BOLD = 800; // 0x320
+ field public static final int FONT_WEIGHT_EXTRA_LIGHT = 200; // 0xc8
+ field public static final int FONT_WEIGHT_LIGHT = 300; // 0x12c
+ field public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+ field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+ field public static final int FONT_WEIGHT_SEMI_BOLD = 600; // 0x258
+ field public static final int FONT_WEIGHT_THIN = 100; // 0x64
+ }
+
+ public static class Font.Builder {
+ ctor public Font.Builder(java.nio.ByteBuffer);
+ ctor public Font.Builder(java.io.File) throws java.io.IOException;
+ ctor public Font.Builder(java.io.FileDescriptor) throws java.io.IOException;
+ ctor public Font.Builder(java.io.FileDescriptor, long, long) throws java.io.IOException;
+ ctor public Font.Builder(android.content.res.AssetManager, java.lang.String) throws java.io.IOException;
+ ctor public Font.Builder(android.content.res.Resources, int) throws java.io.IOException;
+ method public android.graphics.fonts.Font build();
+ method public android.graphics.fonts.Font.Builder setFontVariationSettings(java.lang.String);
+ method public android.graphics.fonts.Font.Builder setFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
+ method public android.graphics.fonts.Font.Builder setItalic(boolean);
+ method public android.graphics.fonts.Font.Builder setTtcIndex(int);
+ method public android.graphics.fonts.Font.Builder setWeight(int);
+ }
+
public final class FontVariationAxis {
ctor public FontVariationAxis(java.lang.String, float);
method public static android.graphics.fonts.FontVariationAxis[] fromFontVariationSettings(java.lang.String);
@@ -32171,6 +32207,7 @@
public class Binder implements android.os.IBinder {
ctor public Binder();
+ ctor public Binder(java.lang.String);
method public void attachInterface(android.os.IInterface, java.lang.String);
method public static final long clearCallingIdentity();
method public void dump(java.io.FileDescriptor, java.lang.String[]);
@@ -39817,9 +39854,11 @@
method public int getDesiredMinimumHeight();
method public int getDesiredMinimumWidth();
method public android.view.SurfaceHolder getSurfaceHolder();
+ method public boolean isInAmbientMode();
method public boolean isPreview();
method public boolean isVisible();
method public void notifyColorsChanged();
+ method public void onAmbientModeChanged(boolean, boolean);
method public void onApplyWindowInsets(android.view.WindowInsets);
method public android.os.Bundle onCommand(java.lang.String, int, int, int, android.os.Bundle, boolean);
method public android.app.WallpaperColors onComputeColors();
@@ -48821,6 +48860,7 @@
method public void dispatchOnGlobalLayout();
method public boolean dispatchOnPreDraw();
method public boolean isAlive();
+ method public void registerFrameCommitCallback(java.lang.Runnable);
method public deprecated void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
method public void removeOnDrawListener(android.view.ViewTreeObserver.OnDrawListener);
method public void removeOnGlobalFocusChangeListener(android.view.ViewTreeObserver.OnGlobalFocusChangeListener);
@@ -48830,6 +48870,7 @@
method public void removeOnTouchModeChangeListener(android.view.ViewTreeObserver.OnTouchModeChangeListener);
method public void removeOnWindowAttachListener(android.view.ViewTreeObserver.OnWindowAttachListener);
method public void removeOnWindowFocusChangeListener(android.view.ViewTreeObserver.OnWindowFocusChangeListener);
+ method public boolean unregisterFrameCommitCallback(java.lang.Runnable);
}
public static abstract interface ViewTreeObserver.OnDrawListener {
diff --git a/api/system-current.txt b/api/system-current.txt
index 924d3af..01f4709 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4524,9 +4524,11 @@
public abstract class AutofillFieldClassificationService extends android.app.Service {
method public android.os.IBinder onBind(android.content.Intent);
method public float[][] onGetScores(java.lang.String, android.os.Bundle, java.util.List<android.view.autofill.AutofillValue>, java.util.List<java.lang.String>);
+ field public static final java.lang.String RESOURCE_AVAILABLE_ALGORITHMS = "autofill_field_classification_available_algorithms";
+ field public static final java.lang.String RESOURCE_DEFAULT_ALGORITHM = "autofill_field_classification_default_algorithm";
field public static final java.lang.String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
- field public static final java.lang.String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = "android.autofill.field_classification.available_algorithms";
- field public static final java.lang.String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM = "android.autofill.field_classification.default_algorithm";
+ field public static final deprecated java.lang.String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = "android.autofill.field_classification.available_algorithms";
+ field public static final deprecated java.lang.String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM = "android.autofill.field_classification.default_algorithm";
}
}
@@ -4665,6 +4667,7 @@
field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
field public static final java.lang.String KEY_PEOPLE = "key_people";
field public static final java.lang.String KEY_SMART_ACTIONS = "key_smart_actions";
+ field public static final java.lang.String KEY_SMART_REPLIES = "key_smart_replies";
field public static final java.lang.String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
field public static final java.lang.String KEY_USER_SENTIMENT = "key_user_sentiment";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 5bd6dc8..1d08da5 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1044,6 +1044,7 @@
field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
field public static final java.lang.String KEY_PEOPLE = "key_people";
field public static final java.lang.String KEY_SMART_ACTIONS = "key_smart_actions";
+ field public static final java.lang.String KEY_SMART_REPLIES = "key_smart_replies";
field public static final java.lang.String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
field public static final java.lang.String KEY_USER_SENTIMENT = "key_user_sentiment";
}
@@ -1467,6 +1468,11 @@
method public static int getLongPressTooltipHideTimeout();
}
+ public final class ViewTreeObserver {
+ method public void registerFrameCommitCallback(java.lang.Runnable);
+ method public boolean unregisterFrameCommitCallback(java.lang.Runnable);
+ }
+
public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
index caac677..22cb2f5 100644
--- a/cmds/statsd/src/external/StatsPuller.h
+++ b/cmds/statsd/src/external/StatsPuller.h
@@ -37,6 +37,8 @@
virtual ~StatsPuller() {}
+ // Pulls the data. The returned data will have elapsedTimeNs set as timeNs
+ // and will have wallClockTimeNs set as current wall clock time.
bool Pull(const int64_t timeNs, std::vector<std::shared_ptr<LogEvent>>* data);
// Clear cache immediately
diff --git a/cmds/statsd/src/external/StatsPullerManager.h b/cmds/statsd/src/external/StatsPullerManager.h
index 45efc4a..bbf5d9d 100644
--- a/cmds/statsd/src/external/StatsPullerManager.h
+++ b/cmds/statsd/src/external/StatsPullerManager.h
@@ -53,9 +53,12 @@
virtual ~StatsPullerManager() {
}
+ // Registers a receiver for tagId. It will be pulled on the nextPullTimeNs
+ // and then every intervalNs thereafter.
virtual void RegisterReceiver(int tagId, wp<PullDataReceiver> receiver, int64_t nextPullTimeNs,
int64_t intervalNs);
+ // Stop listening on a tagId.
virtual void UnRegisterReceiver(int tagId, wp<PullDataReceiver> receiver);
// Verify if we know how to pull for this matcher
@@ -63,11 +66,16 @@
void OnAlarmFired(const int64_t timeNs);
+ // Use respective puller to pull the data. The returned data will have
+ // elapsedTimeNs set as timeNs and will have wallClockTimeNs set as current
+ // wall clock time.
virtual bool Pull(const int tagId, const int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data);
+ // Clear pull data cache immediately.
int ForceClearPullerCache();
+ // Clear pull data cache if it is beyond respective cool down time.
int ClearPullerCacheIfNecessary(int64_t timestampNs);
void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService);
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index a894782..bd94800 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -66,8 +66,8 @@
CountMetricProducer::CountMetricProducer(const ConfigKey& key, const CountMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard,
- const int64_t startTimeNs)
- : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) {
+ const int64_t timeBaseNs, const int64_t startTimeNs)
+ : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard) {
if (metric.has_bucket()) {
mBucketSizeNs =
TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket()) * 1000000;
@@ -100,6 +100,10 @@
mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
+ flushIfNeededLocked(startTimeNs);
+ // Adjust start for partial bucket
+ mCurrentBucketStartTimeNs = startTimeNs;
+
VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
(long long)mBucketSizeNs, (long long)mTimeBaseNs);
}
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 520d5de..39d4ae2 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -42,7 +42,7 @@
public:
CountMetricProducer(const ConfigKey& key, const CountMetric& countMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
- const int64_t startTimeNs);
+ const int64_t timeBaseNs, const int64_t startTimeNs);
virtual ~CountMetricProducer();
@@ -98,6 +98,7 @@
FRIEND_TEST(CountMetricProducerTest, TestAnomalyDetectionUnSliced);
FRIEND_TEST(CountMetricProducerTest, TestEventWithAppUpgrade);
FRIEND_TEST(CountMetricProducerTest, TestEventWithAppUpgradeInNextBucket);
+ FRIEND_TEST(CountMetricProducerTest, TestFirstBucket);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index a19eb0b..9d9e5be 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -68,8 +68,8 @@
const bool nesting,
const sp<ConditionWizard>& wizard,
const FieldMatcher& internalDimensions,
- const int64_t startTimeNs)
- : MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard),
+ const int64_t timeBaseNs, const int64_t startTimeNs)
+ : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard),
mAggregationType(metric.aggregation_type()),
mStartIndex(startIndex),
mStopIndex(stopIndex),
@@ -128,6 +128,9 @@
mMetric2ConditionLinks.begin()->conditionFields);
}
}
+ flushIfNeededLocked(startTimeNs);
+ // Adjust start for partial bucket
+ mCurrentBucketStartTimeNs = startTimeNs;
VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
(long long)mBucketSizeNs, (long long)mTimeBaseNs);
}
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index c496b12..12addb8 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -42,7 +42,7 @@
const int conditionIndex, const size_t startIndex,
const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
const sp<ConditionWizard>& wizard,
- const FieldMatcher& internalDimensions, const int64_t startTimeNs);
+ const FieldMatcher& internalDimensions, const int64_t timeBaseNs, const int64_t startTimeNs);
virtual ~DurationMetricProducer();
@@ -141,6 +141,7 @@
FRIEND_TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgrade);
FRIEND_TEST(DurationMetricTrackerTest, TestMaxDurationWithUpgradeInNextBucket);
FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicates);
+ FRIEND_TEST(DurationMetricTrackerTest, TestFirstBucket);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index a779410..fbe0b21 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -76,6 +76,7 @@
: MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard),
mPullerManager(pullerManager),
mPullTagId(pullTagId),
+ mIsPulled(pullTagId != -1),
mMinBucketSizeNs(metric.min_bucket_size_nanos()),
mDimensionSoftLimit(StatsdStats::kAtomDimensionKeySizeLimitMap.find(pullTagId) !=
StatsdStats::kAtomDimensionKeySizeLimitMap.end()
@@ -125,11 +126,17 @@
flushIfNeededLocked(startTimeNs);
// Kicks off the puller immediately.
- if (mPullTagId != -1 && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
+ if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
mPullerManager->RegisterReceiver(mPullTagId, this, getCurrentBucketEndTimeNs(),
mBucketSizeNs);
}
+ // Adjust start for partial bucket
+ mCurrentBucketStartTimeNs = startTimeNs;
+ if (mIsPulled) {
+ pullLocked(startTimeNs);
+ }
+
VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
(long long)metric.id(), (long long)mBucketSizeNs, (long long)mTimeBaseNs,
mConditionSliced);
@@ -137,7 +144,7 @@
GaugeMetricProducer::~GaugeMetricProducer() {
VLOG("~GaugeMetricProducer() called");
- if (mPullTagId != -1 && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
+ if (mIsPulled && mSamplingType == GaugeMetric::RANDOM_ONE_SAMPLE) {
mPullerManager->UnRegisterReceiver(mPullTagId, this);
}
}
@@ -323,13 +330,11 @@
if (!triggerPuller) {
return;
}
-
vector<std::shared_ptr<LogEvent>> allData;
if (!mPullerManager->Pull(mPullTagId, timestampNs, &allData)) {
- ALOGE("Gauge Stats puller failed for tag: %d", mPullTagId);
+ ALOGE("Gauge Stats puller failed for tag: %d at %lld", mPullTagId, (long long)timestampNs);
return;
}
-
for (const auto& data : allData) {
onMatchedLogEventLocked(0, *data);
}
@@ -340,8 +345,7 @@
VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
flushIfNeededLocked(eventTimeNs);
mCondition = conditionMet;
-
- if (mPullTagId != -1) {
+ if (mIsPulled) {
pullLocked(eventTimeNs);
} // else: Push mode. No need to proactively pull the gauge data.
}
@@ -354,7 +358,7 @@
// If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
// pull for every dimension.
mCondition = overallCondition;
- if (mPullTagId != -1) {
+ if (mIsPulled) {
pullLocked(eventTimeNs);
} // else: Push mode. No need to proactively pull the gauge data.
}
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 6984aa2..cc65440 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -77,7 +77,7 @@
}
flushCurrentBucketLocked(eventTimeNs);
mCurrentBucketStartTimeNs = eventTimeNs;
- if (mPullTagId != -1) {
+ if (mIsPulled) {
pullLocked(eventTimeNs);
}
};
@@ -121,6 +121,9 @@
// tagId for pulled data. -1 if this is not pulled
const int mPullTagId;
+ // if this is pulled metric
+ const bool mIsPulled;
+
// Save the past buckets and we can clear when the StatsLogReport is dumped.
std::unordered_map<MetricDimensionKey, std::vector<GaugeBucket>> mPastBuckets;
@@ -159,12 +162,13 @@
const size_t mGaugeAtomsPerDimensionLimit;
- FRIEND_TEST(GaugeMetricProducerTest, TestWithCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestWithSlicedCondition);
- FRIEND_TEST(GaugeMetricProducerTest, TestNoCondition);
+ FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition);
+ FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition);
+ FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition);
FRIEND_TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade);
FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithUpgrade);
- FRIEND_TEST(GaugeMetricProducerTest, TestAnomalyDetection);
+ FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection);
+ FRIEND_TEST(GaugeMetricProducerTest, TestFirstBucket);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index c6f7bb4..16447e8 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -64,8 +64,8 @@
const int FIELD_ID_DIMENSION_LEAF_IN_WHAT = 4;
const int FIELD_ID_DIMENSION_LEAF_IN_CONDITION = 5;
// for ValueBucketInfo
-const int FIELD_ID_VALUE_LONG = 3;
-const int FIELD_ID_VALUE_DOUBLE = 7;
+const int FIELD_ID_VALUE_LONG = 7;
+const int FIELD_ID_VALUE_DOUBLE = 8;
const int FIELD_ID_BUCKET_NUM = 4;
const int FIELD_ID_START_BUCKET_ELAPSED_MILLIS = 5;
const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;
@@ -74,7 +74,7 @@
ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard, const int pullTagId,
- const int64_t timeBaseNs, const int64_t startTimestampNs,
+ const int64_t timeBaseNs, const int64_t startTimeNs,
const sp<StatsPullerManager>& pullerManager)
: MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard),
mPullerManager(pullerManager),
@@ -127,13 +127,20 @@
mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
HasPositionALL(metric.dimensions_in_condition());
- flushIfNeededLocked(startTimestampNs);
+ flushIfNeededLocked(startTimeNs);
// Kicks off the puller immediately.
if (mIsPulled) {
- mPullerManager->RegisterReceiver(mPullTagId, this,
- mCurrentBucketStartTimeNs + mBucketSizeNs, mBucketSizeNs);
+ mPullerManager->RegisterReceiver(mPullTagId, this, getCurrentBucketEndTimeNs(),
+ mBucketSizeNs);
}
+ // TODO: Only do this for partial buckets like first bucket. All other buckets should use
+ // flushIfNeeded to adjust start and end to bucket boundaries.
+ // Adjust start for partial bucket
+ mCurrentBucketStartTimeNs = startTimeNs;
+ if (mIsPulled) {
+ pullLocked(startTimeNs);
+ }
VLOG("value metric %lld created. bucket size %lld start_time: %lld",
(long long)metric.id(), (long long)mBucketSizeNs, (long long)mTimeBaseNs);
}
@@ -280,16 +287,19 @@
flushIfNeededLocked(eventTimeNs);
if (mIsPulled) {
- vector<shared_ptr<LogEvent>> allData;
- if (mPullerManager->Pull(mPullTagId, eventTimeNs, &allData)) {
- if (allData.size() == 0) {
- return;
- }
- for (const auto& data : allData) {
- onMatchedLogEventLocked(0, *data);
- }
+ pullLocked(eventTimeNs);
+ }
+}
+
+void ValueMetricProducer::pullLocked(const int64_t timestampNs) {
+ vector<std::shared_ptr<LogEvent>> allData;
+ if (mPullerManager->Pull(mPullTagId, timestampNs, &allData)) {
+ if (allData.size() == 0) {
+ return;
}
- return;
+ for (const auto& data : allData) {
+ onMatchedLogEventLocked(0, *data);
+ }
}
}
@@ -306,12 +316,14 @@
int64_t eventTime = mTimeBaseNs +
((realEventTime - mTimeBaseNs) / mBucketSizeNs) * mBucketSizeNs;
+ // close the end of the bucket
mCondition = false;
for (const auto& data : allData) {
data->setElapsedTimestampNs(eventTime - 1);
onMatchedLogEventLocked(0, *data);
}
+ // start a new bucket
mCondition = true;
for (const auto& data : allData) {
data->setElapsedTimestampNs(eventTime);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 188e3de..b2f0b6f 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -55,7 +55,7 @@
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
- if (mPullTagId != -1 && (mCondition == true || mConditionTrackerIndex < 0) ) {
+ if (mIsPulled && (mCondition == true || mConditionTrackerIndex < 0)) {
vector<shared_ptr<LogEvent>> allData;
mPullerManager->Pull(mPullTagId, eventTimeNs, &allData);
if (allData.size() == 0) {
@@ -159,6 +159,8 @@
// Util function to check whether the specified dimension hits the guardrail.
bool hitGuardRailLocked(const MetricDimensionKey& newKey);
+ void pullLocked(const int64_t timestampNs);
+
static const size_t kBucketSize = sizeof(ValueBucket{});
const size_t mDimensionSoftLimit;
@@ -171,7 +173,7 @@
const Type mValueType;
- FRIEND_TEST(ValueMetricProducerTest, TestNonDimensionalEvents);
+ FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition);
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset);
FRIEND_TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition);
@@ -190,6 +192,7 @@
FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateAvg);
FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSum);
FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSumSliced);
+ FRIEND_TEST(ValueMetricProducerTest, TestFirstBucket);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index e03edb3..ff48d02 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -312,7 +312,7 @@
}
sp<MetricProducer> countProducer =
- new CountMetricProducer(key, metric, conditionIndex, wizard, timeBaseTimeNs);
+ new CountMetricProducer(key, metric, conditionIndex, wizard, timeBaseTimeNs, currentTimeNs);
allMetricProducers.push_back(countProducer);
}
@@ -382,7 +382,7 @@
sp<MetricProducer> durationMetric = new DurationMetricProducer(
key, metric, conditionIndex, trackerIndices[0], trackerIndices[1],
- trackerIndices[2], nesting, wizard, internalDimensions, timeBaseTimeNs);
+ trackerIndices[2], nesting, wizard, internalDimensions, timeBaseTimeNs, currentTimeNs);
allMetricProducers.push_back(durationMetric);
}
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index cfd6269..db7e680 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -106,10 +106,12 @@
optional int64 end_bucket_elapsed_nanos = 2;
- oneof values {
- int64 value_long = 3;
+ optional int64 value = 3 [deprecated = true];
- double value_double = 7;
+ oneof values {
+ int64 value_long = 7;
+
+ double value_double = 8;
}
optional int64 bucket_num = 4;
diff --git a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
index 9a8919e..67c704e 100644
--- a/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/CountMetricProducer_test.cpp
@@ -37,6 +37,19 @@
const ConfigKey kConfigKey(0, 12345);
+TEST(CountMetricProducerTest, TestFirstBucket) {
+ CountMetric metric;
+ metric.set_id(1);
+ metric.set_bucket(ONE_MINUTE);
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+
+ CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ 5, 600 * NS_PER_SEC + NS_PER_SEC/2);
+ EXPECT_EQ(600500000000, countProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(10, countProducer.mCurrentBucketNum);
+ EXPECT_EQ(660000000005, countProducer.getCurrentBucketEndTimeNs());
+}
+
TEST(CountMetricProducerTest, TestNonDimensionalEvents) {
int64_t bucketStartTimeNs = 10000000000;
int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
@@ -56,8 +69,7 @@
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- bucketStartTimeNs);
- countProducer.setBucketSize(60 * NS_PER_SEC);
+ bucketStartTimeNs, bucketStartTimeNs);
// 2 events in bucket 1.
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
@@ -119,8 +131,7 @@
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- CountMetricProducer countProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs);
- countProducer.setBucketSize(60 * NS_PER_SEC);
+ CountMetricProducer countProducer(kConfigKey, metric, 1, wizard, bucketStartTimeNs, bucketStartTimeNs);
countProducer.onConditionChanged(true, bucketStartTimeNs);
countProducer.onMatchedLogEvent(1 /*matcher index*/, event1);
@@ -181,8 +192,7 @@
EXPECT_CALL(*wizard, query(_, key2, _, _, _, _)).WillOnce(Return(ConditionState::kTrue));
CountMetricProducer countProducer(kConfigKey, metric, 1 /*condition tracker index*/, wizard,
- bucketStartTimeNs);
- countProducer.setBucketSize(60 * NS_PER_SEC);
+ bucketStartTimeNs, bucketStartTimeNs);
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
countProducer.flushIfNeededLocked(bucketStartTimeNs + 1);
@@ -221,8 +231,7 @@
event1.init();
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
- bucketStartTimeNs);
- countProducer.setBucketSize(60 * NS_PER_SEC);
+ bucketStartTimeNs, bucketStartTimeNs);
sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
EXPECT_TRUE(anomalyTracker != nullptr);
@@ -280,8 +289,7 @@
event1.init();
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
CountMetricProducer countProducer(kConfigKey, metric, -1 /* no condition */, wizard,
- bucketStartTimeNs);
- countProducer.setBucketSize(60 * NS_PER_SEC);
+ bucketStartTimeNs, bucketStartTimeNs);
// Bucket is flushed yet.
countProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
@@ -337,8 +345,7 @@
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
CountMetricProducer countProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- bucketStartTimeNs);
- countProducer.setBucketSize(60 * NS_PER_SEC);
+ bucketStartTimeNs, bucketStartTimeNs);
sp<AnomalyTracker> anomalyTracker = countProducer.addAnomalyTracker(alert, alarmMonitor);
diff --git a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
index 7ef8c5b..b540964 100644
--- a/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/DurationMetricProducer_test.cpp
@@ -39,6 +39,23 @@
const ConfigKey kConfigKey(0, 12345);
+TEST(DurationMetricTrackerTest, TestFirstBucket) {
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ DurationMetric metric;
+ metric.set_id(1);
+ metric.set_bucket(ONE_MINUTE);
+ metric.set_aggregation_type(DurationMetric_AggregationType_SUM);
+
+ FieldMatcher dimensions;
+ DurationMetricProducer durationProducer(
+ kConfigKey, metric, -1 /*no condition*/, 1 /* start index */, 2 /* stop index */,
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, 5, 600 * NS_PER_SEC + NS_PER_SEC/2);
+
+ EXPECT_EQ(600500000000, durationProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(10, durationProducer.mCurrentBucketNum);
+ EXPECT_EQ(660000000005, durationProducer.getCurrentBucketEndTimeNs());
+}
+
TEST(DurationMetricTrackerTest, TestNoCondition) {
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
int64_t bucketStartTimeNs = 10000000000;
@@ -58,8 +75,7 @@
FieldMatcher dimensions;
DurationMetricProducer durationProducer(
kConfigKey, metric, -1 /*no condition*/, 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
- durationProducer.setBucketSize(60 * NS_PER_SEC);
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
durationProducer.onMatchedLogEvent(1 /* start index*/, event1);
durationProducer.onMatchedLogEvent(2 /* stop index*/, event2);
@@ -100,8 +116,7 @@
FieldMatcher dimensions;
DurationMetricProducer durationProducer(
kConfigKey, metric, 0 /* condition index */, 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
- durationProducer.setBucketSize(60 * NS_PER_SEC);
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
EXPECT_FALSE(durationProducer.mCondition);
EXPECT_FALSE(durationProducer.isConditionSliced());
@@ -151,8 +166,7 @@
FieldMatcher dimensions;
DurationMetricProducer durationProducer(
kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
- durationProducer.setBucketSize(60 * NS_PER_SEC);
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
LogEvent start_event(tagId, startTimeNs);
start_event.init();
@@ -206,8 +220,7 @@
FieldMatcher dimensions;
DurationMetricProducer durationProducer(
kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
- durationProducer.setBucketSize(60 * NS_PER_SEC);
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
LogEvent start_event(tagId, startTimeNs);
start_event.init();
@@ -261,8 +274,7 @@
FieldMatcher dimensions;
DurationMetricProducer durationProducer(
kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
- durationProducer.setBucketSize(60 * NS_PER_SEC);
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
sp<AnomalyTracker> anomalyTracker = durationProducer.addAnomalyTracker(alert, alarmMonitor);
EXPECT_TRUE(anomalyTracker != nullptr);
@@ -300,8 +312,7 @@
FieldMatcher dimensions;
DurationMetricProducer durationProducer(
kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
- durationProducer.setBucketSize(60 * NS_PER_SEC);
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
LogEvent start_event(tagId, startTimeNs);
start_event.init();
@@ -348,8 +359,7 @@
FieldMatcher dimensions;
DurationMetricProducer durationProducer(
kConfigKey, metric, -1 /* no condition */, 1 /* start index */, 2 /* stop index */,
- 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs);
- durationProducer.setBucketSize(60 * NS_PER_SEC);
+ 3 /* stop_all index */, false /*nesting*/, wizard, dimensions, bucketStartTimeNs, bucketStartTimeNs);
LogEvent start_event(tagId, startTimeNs);
start_event.init();
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 19c9f77..2fda858 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -47,7 +47,33 @@
const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
const int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
-TEST(GaugeMetricProducerTest, TestNoCondition) {
+/*
+ * Tests that the first bucket works correctly
+ */
+TEST(GaugeMetricProducerTest, TestFirstBucket) {
+ GaugeMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_gauge_fields_filter()->set_include_all(false);
+ auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
+ gaugeFieldMatcher->set_field(tagId);
+ gaugeFieldMatcher->add_child()->set_field(1);
+ gaugeFieldMatcher->add_child()->set_field(3);
+
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ // statsd started long ago.
+ // The metric starts in the middle of the bucket
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ -1, 5, 600 * NS_PER_SEC + NS_PER_SEC/2, pullerManager);
+
+ EXPECT_EQ(600500000000, gaugeProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(10, gaugeProducer.mCurrentBucketNum);
+ EXPECT_EQ(660000000005, gaugeProducer.getCurrentBucketEndTimeNs());
+}
+
+TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition) {
GaugeMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
@@ -62,6 +88,16 @@
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ event->write(3);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
@@ -83,7 +119,9 @@
EXPECT_EQ(10, it->mValue.int_value);
it++;
EXPECT_EQ(11, it->mValue.int_value);
- EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+ EXPECT_EQ(3, gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms
+ .front().mFields->begin()->mValue.int_value);
allData.clear();
std::shared_ptr<LogEvent> event2 = std::make_shared<LogEvent>(tagId, bucket3StartTimeNs + 10);
@@ -102,7 +140,7 @@
EXPECT_EQ(25, it->mValue.int_value);
// One dimension.
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
EXPECT_EQ(10L, it->mValue.int_value);
@@ -114,7 +152,7 @@
EXPECT_EQ(0UL, gaugeProducer.mCurrentSlicedBucket->size());
// One dimension.
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, gaugeProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(3UL, gaugeProducer.mPastBuckets.begin()->second.size());
it = gaugeProducer.mPastBuckets.begin()->second.back().mGaugeAtoms.front().mFields->begin();
EXPECT_EQ(INT, it->mValue.getType());
EXPECT_EQ(24L, it->mValue.int_value);
@@ -210,6 +248,7 @@
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Return(false))
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
@@ -263,7 +302,7 @@
->mValue.int_value);
}
-TEST(GaugeMetricProducerTest, TestWithCondition) {
+TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
GaugeMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
@@ -333,7 +372,7 @@
->mValue.int_value);
}
-TEST(GaugeMetricProducerTest, TestWithSlicedCondition) {
+TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition) {
const int conditionTag = 65;
GaugeMetric metric;
metric.set_id(1111111);
@@ -409,13 +448,14 @@
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
}
-TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
+TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection) {
sp<AlarmMonitor> alarmMonitor;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
GaugeMetric metric;
metric.set_id(metricId);
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 3559a7c..57aab97 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -50,9 +50,32 @@
const int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
/*
+ * Tests that the first bucket works correctly
+ */
+TEST(ValueMetricProducerTest, TestFirstBucket) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ // statsd started long ago.
+ // The metric starts in the middle of the bucket
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ -1, 5, 600 * NS_PER_SEC + NS_PER_SEC/2, pullerManager);
+
+ EXPECT_EQ(600500000000, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(10, valueProducer.mCurrentBucketNum);
+ EXPECT_EQ(660000000005, valueProducer.getCurrentBucketEndTimeNs());
+}
+
+/*
* Tests pulled atoms with no conditions
*/
-TEST(ValueMetricProducerTest, TestNonDimensionalEvents) {
+TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
ValueMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
@@ -63,10 +86,20 @@
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ event->write(tagId);
+ event->write(3);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -85,7 +118,8 @@
EXPECT_EQ(true, curInterval.startUpdated);
EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(11, curInterval.start.long_value);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -99,9 +133,9 @@
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
// tartUpdated:false sum:12
EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(0, curInterval.value.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
allData.clear();
@@ -115,9 +149,9 @@
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
// startUpdated:false sum:12
EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(0, curInterval.value.long_value);
+ EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(3UL, valueProducer.mPastBuckets.begin()->second.size());
EXPECT_EQ(13, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
}
@@ -136,10 +170,10 @@
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -205,10 +239,10 @@
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -275,6 +309,17 @@
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ // should not take effect
+ .WillOnce(Invoke([](int tagId, int64_t timeNs,
+ vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ event->write(tagId);
+ event->write(3);
+ event->init();
+ data->push_back(event);
+ return true;
+ }))
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
@@ -298,7 +343,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
// has one slice
@@ -349,7 +393,6 @@
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -392,6 +435,7 @@
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Return(false))
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
@@ -404,7 +448,6 @@
}));
ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
vector<shared_ptr<LogEvent>> allData;
allData.clear();
@@ -447,6 +490,7 @@
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Return(false))
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
@@ -469,7 +513,6 @@
}));
ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 1);
valueProducer.onConditionChanged(false, bucket2StartTimeNs-100);
@@ -496,7 +539,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -538,7 +580,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -612,7 +653,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
-1 /*not pulled*/, bucketStartTimeNs, bucketStartTimeNs,
pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
sp<AnomalyTracker> anomalyTracker = valueProducer.addAnomalyTracker(alert, alarmMonitor);
@@ -687,10 +727,10 @@
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
vector<shared_ptr<LogEvent>> allData;
// pull 1
@@ -770,6 +810,7 @@
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Return(false))
// condition becomes true
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
@@ -795,7 +836,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
// has one slice
@@ -849,6 +889,7 @@
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Return(false))
// condition becomes true
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
@@ -885,7 +926,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
// has one slice
@@ -947,6 +987,7 @@
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
+ .WillOnce(Return(false))
// condition becomes true
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
@@ -972,7 +1013,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
// has one slice
@@ -1022,7 +1062,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1065,7 +1104,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1108,7 +1146,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1154,7 +1191,6 @@
ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
event1->write(1);
@@ -1218,14 +1254,12 @@
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)).WillOnce(Return(ConditionState::kFalse));
-
EXPECT_CALL(*wizard, query(_, key2, _, _, _, _)).WillOnce(Return(ConditionState::kTrue));
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.setBucketSize(60 * NS_PER_SEC);
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blacklist.txt
index 3a9e2d1..dca3b52 100644
--- a/config/hiddenapi-force-blacklist.txt
+++ b/config/hiddenapi-force-blacklist.txt
@@ -1,38 +1,38 @@
Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V
Ljava/lang/invoke/MethodHandles$Lookup;->IMPL_LOOKUP:Ljava/lang/invoke/MethodHandles$Lookup;
Ljava/lang/invoke/VarHandle;->acquireFence()V
-Ljava/lang/invoke/VarHandle;->compareAndExchange([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->compareAndExchangeAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->compareAndExchangeRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->compareAndSet([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->compareAndExchange([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndExchangeAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndExchangeRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndSet([Ljava/lang/Object;)Z
Ljava/lang/invoke/VarHandle;->fullFence()V
-Ljava/lang/invoke/VarHandle;->get([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndAdd([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndAddAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndAddRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseAnd([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseAndAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseAndRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseOr([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseOrAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseOrRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseXor([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseXorAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndBitwiseXorRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndSet([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndSetAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getAndSetRelease([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getOpaque([[Ljava/lang/Object;)Ljava/lang/Object;
-Ljava/lang/invoke/VarHandle;->getVolatile([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->get([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAdd([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAddAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAddRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAnd([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAndAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAndRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOr([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOrAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOrRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXor([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXorAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXorRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSet([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSetAcquire([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSetRelease([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getOpaque([Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getVolatile([Ljava/lang/Object;)Ljava/lang/Object;
Ljava/lang/invoke/VarHandle;->loadLoadFence()V
Ljava/lang/invoke/VarHandle;->releaseFence()V
-Ljava/lang/invoke/VarHandle;->set([[Ljava/lang/Object;)V
-Ljava/lang/invoke/VarHandle;->setOpaque([[Ljava/lang/Object;)V
-Ljava/lang/invoke/VarHandle;->setRelease([[Ljava/lang/Object;)V
-Ljava/lang/invoke/VarHandle;->setVolatile([[Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->set([Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setOpaque([Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setRelease([Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setVolatile([Ljava/lang/Object;)V
Ljava/lang/invoke/VarHandle;->storeStoreFence()V
-Ljava/lang/invoke/VarHandle;->weakCompareAndSet([[Ljava/lang/Object;)Z
-Ljava/lang/invoke/VarHandle;->weakCompareAndSetAcquire([[Ljava/lang/Object;)Z
-Ljava/lang/invoke/VarHandle;->weakCompareAndSetPlain([[Ljava/lang/Object;)Z
-Ljava/lang/invoke/VarHandle;->weakCompareAndSetRelease([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSet([Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetAcquire([Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetPlain([Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetRelease([Ljava/lang/Object;)Z
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 4484c8f..0b94c27 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,6 +1,3 @@
-Landroid/accessibilityservice/AccessibilityService;->mInfo:Landroid/accessibilityservice/AccessibilityServiceInfo;
-Landroid/accessibilityservice/AccessibilityService;->mWindowToken:Landroid/os/IBinder;
-Landroid/accessibilityservice/AccessibilityServiceInfo;->setCapabilities(I)V
Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;-><init>()V
Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accessibilityservice/IAccessibilityServiceConnection;
Landroid/accounts/Account;->accessId:Ljava/lang/String;
@@ -51,13 +48,6 @@
Landroid/accounts/IAccountManagerResponse$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManagerResponse;
Landroid/accounts/IAccountManagerResponse;->onError(ILjava/lang/String;)V
Landroid/accounts/IAccountManagerResponse;->onResult(Landroid/os/Bundle;)V
-Landroid/animation/Animator;->reverse()V
-Landroid/animation/ArgbEvaluator;->getInstance()Landroid/animation/ArgbEvaluator;
-Landroid/animation/LayoutTransition;->cancel()V
-Landroid/animation/LayoutTransition;->cancel(I)V
-Landroid/animation/ValueAnimator;->animateValue(F)V
-Landroid/animation/ValueAnimator;->mDuration:J
-Landroid/animation/ValueAnimator;->sDurationScale:F
Landroid/app/ActionBar;->collapseActionView()Z
Landroid/app/ActionBar;->DISPLAY_TITLE_MULTIPLE_LINES:I
Landroid/app/ActionBar;->setShowHideAnimationEnabled(Z)V
@@ -533,7 +523,7 @@
Landroid/app/DownloadManager$Request;->mUri:Landroid/net/Uri;
Landroid/app/DownloadManager;->getWhereArgsForIds([J)[Ljava/lang/String;
Landroid/app/DownloadManager;->getWhereClauseForIds([J)Ljava/lang/String;
-Landroid/app/DownloadManager;->restartDownload([[J)V
+Landroid/app/DownloadManager;->restartDownload([J)V
Landroid/app/DownloadManager;->setAccessAllDownloads(Z)V
Landroid/app/DownloadManager;->setAccessFilename(Z)V
Landroid/app/DownloadManager;->UNDERLYING_COLUMNS:[Ljava/lang/String;
@@ -1049,7 +1039,6 @@
Landroid/bluetooth/BluetoothClass;->doesClassMatch(I)Z
Landroid/bluetooth/BluetoothClass;->PROFILE_A2DP:I
Landroid/bluetooth/BluetoothClass;->PROFILE_HEADSET:I
-Landroid/bluetooth/BluetoothCodecConfig;
Landroid/bluetooth/BluetoothCodecConfig;-><init>(IIIIIJJJJ)V
Landroid/bluetooth/BluetoothCodecConfig;->BITS_PER_SAMPLE_16:I
Landroid/bluetooth/BluetoothCodecConfig;->BITS_PER_SAMPLE_24:I
@@ -1085,7 +1074,6 @@
Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_LDAC:I
Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_MAX:I
Landroid/bluetooth/BluetoothCodecConfig;->SOURCE_CODEC_TYPE_SBC:I
-Landroid/bluetooth/BluetoothCodecStatus;
Landroid/bluetooth/BluetoothCodecStatus;->EXTRA_CODEC_STATUS:Ljava/lang/String;
Landroid/bluetooth/BluetoothCodecStatus;->getCodecConfig()Landroid/bluetooth/BluetoothCodecConfig;
Landroid/bluetooth/BluetoothCodecStatus;->getCodecsLocalCapabilities()[Landroid/bluetooth/BluetoothCodecConfig;
@@ -1453,10 +1441,15 @@
Landroid/content/pm/ComponentInfo;->getComponentName()Landroid/content/ComponentName;
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->onRemoveCompleted(Ljava/lang/String;Z)V
Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
+Landroid/content/pm/IPackageDataObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/content/pm/IPackageDataObserver$Stub;->TRANSACTION_onRemoveCompleted:I
Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
+Landroid/content/pm/IPackageDeleteObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/content/pm/IPackageDeleteObserver$Stub;->TRANSACTION_packageDeleted:I
Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/pm/IPackageDeleteObserver2$Stub;-><init>()V
@@ -1555,6 +1548,8 @@
Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/content/pm/IPackageStatsObserver$Stub;-><init>()V
Landroid/content/pm/IPackageStatsObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageStatsObserver;
+Landroid/content/pm/IPackageStatsObserver$Stub;->DESCRIPTOR:Ljava/lang/String;
+Landroid/content/pm/IPackageStatsObserver$Stub;->TRANSACTION_onGetStatsCompleted:I
Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IShortcutService;
Landroid/content/pm/LauncherActivityInfo;->mActivityInfo:Landroid/content/pm/ActivityInfo;
@@ -2025,8 +2020,6 @@
Landroid/database/sqlite/SqliteWrapper;->checkSQLiteException(Landroid/content/Context;Landroid/database/sqlite/SQLiteException;)V
Landroid/database/sqlite/SqliteWrapper;->delete(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I
Landroid/database/sqlite/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-Landroid/ddm/DdmHandleAppName;->getAppName()Ljava/lang/String;
-Landroid/ddm/DdmHandleAppName;->setAppName(Ljava/lang/String;I)V
Landroid/filterfw/core/Filter;-><init>(Ljava/lang/String;)V
Landroid/filterfw/core/Filter;->isAvailable(Ljava/lang/String;)Z
Landroid/filterfw/core/Filter;->setInputValue(Ljava/lang/String;Ljava/lang/Object;)V
@@ -2093,268 +2086,7 @@
Landroid/filterfw/GraphEnvironment;-><init>()V
Landroid/filterfw/GraphEnvironment;->getRunner(II)Landroid/filterfw/core/GraphRunner;
Landroid/filterfw/GraphEnvironment;->loadGraph(Landroid/content/Context;I)I
-Landroid/graphics/BaseCanvas;->mNativeCanvasWrapper:J
-Landroid/graphics/Bitmap$Config;->nativeInt:I
-Landroid/graphics/Bitmap$Config;->nativeToConfig(I)Landroid/graphics/Bitmap$Config;
-Landroid/graphics/Bitmap;-><init>(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;)V
-Landroid/graphics/Bitmap;->createAshmemBitmap()Landroid/graphics/Bitmap;
-Landroid/graphics/Bitmap;->createAshmemBitmap(Landroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;
-Landroid/graphics/Bitmap;->getDefaultDensity()I
-Landroid/graphics/Bitmap;->mHeight:I
-Landroid/graphics/Bitmap;->mNativePtr:J
-Landroid/graphics/Bitmap;->mNinePatchChunk:[B
-Landroid/graphics/Bitmap;->mNinePatchInsets:Landroid/graphics/NinePatch$InsetStruct;
-Landroid/graphics/Bitmap;->mWidth:I
-Landroid/graphics/Bitmap;->nativeReconfigure(JIIIZ)V
-Landroid/graphics/Bitmap;->reinit(IIZ)V
-Landroid/graphics/Bitmap;->scaleFromDensity(III)I
-Landroid/graphics/Bitmap;->setDefaultDensity(I)V
-Landroid/graphics/Bitmap;->setNinePatchChunk([B)V
-Landroid/graphics/BitmapFactory;->nativeDecodeAsset(JLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapFactory;->nativeDecodeByteArray([BIILandroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapFactory;->nativeDecodeFileDescriptor(Ljava/io/FileDescriptor;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapFactory;->nativeDecodeStream(Ljava/io/InputStream;[BLandroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapRegionDecoder;-><init>(J)V
-Landroid/graphics/BitmapRegionDecoder;->nativeNewInstance([BIIZ)Landroid/graphics/BitmapRegionDecoder;
-Landroid/graphics/BitmapShader;->mBitmap:Landroid/graphics/Bitmap;
-Landroid/graphics/BitmapShader;->mTileX:I
-Landroid/graphics/BitmapShader;->mTileY:I
-Landroid/graphics/Camera;->native_instance:J
-Landroid/graphics/Canvas;-><init>(J)V
-Landroid/graphics/Canvas;->freeCaches()V
-Landroid/graphics/Canvas;->freeTextLayoutCaches()V
-Landroid/graphics/Canvas;->getGL()Ljavax/microedition/khronos/opengles/GL;
-Landroid/graphics/Canvas;->getNativeCanvasWrapper()J
-Landroid/graphics/Canvas;->mBitmap:Landroid/graphics/Bitmap;
-Landroid/graphics/Canvas;->release()V
-Landroid/graphics/Canvas;->setScreenDensity(I)V
-Landroid/graphics/CanvasProperty;->createFloat(F)Landroid/graphics/CanvasProperty;
-Landroid/graphics/CanvasProperty;->createPaint(Landroid/graphics/Paint;)Landroid/graphics/CanvasProperty;
-Landroid/graphics/ColorMatrixColorFilter;->mMatrix:Landroid/graphics/ColorMatrix;
-Landroid/graphics/ColorMatrixColorFilter;->setColorMatrix(Landroid/graphics/ColorMatrix;)V
-Landroid/graphics/ColorMatrixColorFilter;->setColorMatrixArray([F)V
-Landroid/graphics/drawable/AnimatedImageDrawable;->onAnimationEnd()V
-Landroid/graphics/drawable/AnimatedRotateDrawable;->setFramesCount(I)V
-Landroid/graphics/drawable/AnimatedRotateDrawable;->setFramesDuration(I)V
-Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->mStateIds:Landroid/util/SparseIntArray;
-Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;->mTransitions:Landroid/util/LongSparseLongArray;
-Landroid/graphics/drawable/AnimatedStateListDrawable;->mState:Landroid/graphics/drawable/AnimatedStateListDrawable$AnimatedStateListState;
-Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;->callOnFinished(Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimatorRT;I)V
-Landroid/graphics/drawable/AnimatedVectorDrawable;->forceAnimationOnUI()V
-Landroid/graphics/drawable/AnimatedVectorDrawable;->mAnimatedVectorState:Landroid/graphics/drawable/AnimatedVectorDrawable$AnimatedVectorDrawableState;
-Landroid/graphics/drawable/AnimatedVectorDrawable;->mAnimatorSet:Landroid/graphics/drawable/AnimatedVectorDrawable$VectorDrawableAnimator;
-Landroid/graphics/drawable/AnimationDrawable;->mCurFrame:I
-Landroid/graphics/drawable/BitmapDrawable;->getTint()Landroid/content/res/ColorStateList;
-Landroid/graphics/drawable/BitmapDrawable;->getTintMode()Landroid/graphics/PorterDuff$Mode;
-Landroid/graphics/drawable/BitmapDrawable;->mBitmapState:Landroid/graphics/drawable/BitmapDrawable$BitmapState;
-Landroid/graphics/drawable/BitmapDrawable;->mTargetDensity:I
-Landroid/graphics/drawable/BitmapDrawable;->setBitmap(Landroid/graphics/Bitmap;)V
-Landroid/graphics/drawable/ClipDrawable;->mState:Landroid/graphics/drawable/ClipDrawable$ClipState;
-Landroid/graphics/drawable/ColorDrawable$ColorState;->mUseColor:I
-Landroid/graphics/drawable/ColorDrawable;->mPaint:Landroid/graphics/Paint;
-Landroid/graphics/drawable/Drawable;->inflateWithAttributes(Landroid/content/res/Resources;Lorg/xmlpull/v1/XmlPullParser;Landroid/content/res/TypedArray;I)V
-Landroid/graphics/drawable/Drawable;->mCallback:Ljava/lang/ref/WeakReference;
-Landroid/graphics/drawable/Drawable;->mSrcDensityOverride:I
-Landroid/graphics/drawable/Drawable;->parseTintMode(ILandroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuff$Mode;
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;-><init>(Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;Landroid/graphics/drawable/DrawableContainer;Landroid/content/res/Resources;)V
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mConstantPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mDrawables:[Landroid/graphics/drawable/Drawable;
-Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;->mHasColorFilter:Z
-Landroid/graphics/drawable/DrawableContainer;->mDrawableContainerState:Landroid/graphics/drawable/DrawableContainer$DrawableContainerState;
-Landroid/graphics/drawable/DrawableContainer;->mLastDrawable:Landroid/graphics/drawable/Drawable;
-Landroid/graphics/drawable/DrawableInflater;->mClassLoader:Ljava/lang/ClassLoader;
-Landroid/graphics/drawable/DrawableWrapper;->mState:Landroid/graphics/drawable/DrawableWrapper$DrawableWrapperState;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mAngle:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradient:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mGradientColors:[I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mHeight:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mInnerRadius:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mInnerRadiusRatio:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mOrientation:Landroid/graphics/drawable/GradientDrawable$Orientation;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mPositions:[F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadius:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mRadiusArray:[F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mShape:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mSolidColors:Landroid/content/res/ColorStateList;
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mStrokeDashGap:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mStrokeDashWidth:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mStrokeWidth:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mThickness:I
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mThicknessRatio:F
-Landroid/graphics/drawable/GradientDrawable$GradientState;->mWidth:I
-Landroid/graphics/drawable/GradientDrawable;->mFillPaint:Landroid/graphics/Paint;
-Landroid/graphics/drawable/GradientDrawable;->mGradientState:Landroid/graphics/drawable/GradientDrawable$GradientState;
-Landroid/graphics/drawable/GradientDrawable;->mPadding:Landroid/graphics/Rect;
-Landroid/graphics/drawable/GradientDrawable;->mStrokePaint:Landroid/graphics/Paint;
-Landroid/graphics/drawable/Icon;->createWithResource(Landroid/content/res/Resources;I)Landroid/graphics/drawable/Icon;
-Landroid/graphics/drawable/Icon;->getBitmap()Landroid/graphics/Bitmap;
-Landroid/graphics/drawable/Icon;->getDataBytes()[B
-Landroid/graphics/drawable/Icon;->getDataLength()I
-Landroid/graphics/drawable/Icon;->getDataOffset()I
-Landroid/graphics/drawable/Icon;->getResources()Landroid/content/res/Resources;
-Landroid/graphics/drawable/Icon;->hasTint()Z
-Landroid/graphics/drawable/Icon;->mString1:Ljava/lang/String;
-Landroid/graphics/drawable/Icon;->mType:I
-Landroid/graphics/drawable/InsetDrawable;->mState:Landroid/graphics/drawable/InsetDrawable$InsetState;
-Landroid/graphics/drawable/LayerDrawable$ChildDrawable;->mDrawable:Landroid/graphics/drawable/Drawable;
-Landroid/graphics/drawable/LayerDrawable$LayerState;->mChildren:[Landroid/graphics/drawable/LayerDrawable$ChildDrawable;
-Landroid/graphics/drawable/LayerDrawable;->addLayer(Landroid/graphics/drawable/LayerDrawable$ChildDrawable;)I
-Landroid/graphics/drawable/LayerDrawable;->ensurePadding()V
-Landroid/graphics/drawable/LayerDrawable;->mLayerState:Landroid/graphics/drawable/LayerDrawable$LayerState;
-Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;->mNinePatch:Landroid/graphics/NinePatch;
-Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;
-Landroid/graphics/drawable/RippleDrawable$RippleState;->mColor:Landroid/content/res/ColorStateList;
-Landroid/graphics/drawable/RippleDrawable;->getRipplePaint()Landroid/graphics/Paint;
-Landroid/graphics/drawable/RippleDrawable;->mDensity:I
-Landroid/graphics/drawable/RippleDrawable;->mState:Landroid/graphics/drawable/RippleDrawable$RippleState;
-Landroid/graphics/drawable/RippleDrawable;->setForceSoftware(Z)V
-Landroid/graphics/drawable/RotateDrawable;->mState:Landroid/graphics/drawable/RotateDrawable$RotateState;
-Landroid/graphics/drawable/ScaleDrawable;->mState:Landroid/graphics/drawable/ScaleDrawable$ScaleState;
-Landroid/graphics/drawable/StateListDrawable$StateListState;->addStateSet([ILandroid/graphics/drawable/Drawable;)I
-Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I
-Landroid/graphics/drawable/StateListDrawable;->mStateListState:Landroid/graphics/drawable/StateListDrawable$StateListState;
-Landroid/graphics/drawable/StateListDrawable;->updateStateFromTypedArray(Landroid/content/res/TypedArray;)V
-Landroid/graphics/drawable/TransitionDrawable;->mAlpha:I
-Landroid/graphics/drawable/TransitionDrawable;->mCrossFade:Z
-Landroid/graphics/drawable/TransitionDrawable;->mTo:I
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setPivotX(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setPivotY(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setRotation(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setTranslateX(F)V
-Landroid/graphics/drawable/VectorDrawable$VGroup;->setTranslateY(F)V
-Landroid/graphics/drawable/VectorDrawable;->getTargetByName(Ljava/lang/String;)Ljava/lang/Object;
-Landroid/graphics/drawable/VectorDrawable;->mTintFilter:Landroid/graphics/PorterDuffColorFilter;
-Landroid/graphics/drawable/VectorDrawable;->setAllowCaching(Z)V
-Landroid/graphics/FontFamily;-><init>()V
-Landroid/graphics/FontFamily;-><init>([Ljava/lang/String;I)V
-Landroid/graphics/FontFamily;->abortCreation()V
-Landroid/graphics/FontFamily;->addFontFromAssetManager(Landroid/content/res/AssetManager;Ljava/lang/String;IZIII[Landroid/graphics/fonts/FontVariationAxis;)Z
-Landroid/graphics/FontFamily;->addFontFromBuffer(Ljava/nio/ByteBuffer;I[Landroid/graphics/fonts/FontVariationAxis;II)Z
-Landroid/graphics/FontFamily;->freeze()Z
-Landroid/graphics/FontFamily;->mNativePtr:J
-Landroid/graphics/FontListParser;->parse(Ljava/io/InputStream;)Landroid/text/FontConfig;
-Landroid/graphics/fonts/FontVariationAxis;->mStyleValue:F
-Landroid/graphics/fonts/FontVariationAxis;->mTag:I
-Landroid/graphics/GraphicBuffer;-><init>(IIIIJ)V
-Landroid/graphics/GraphicBuffer;->createFromExisting(IIIIJ)Landroid/graphics/GraphicBuffer;
-Landroid/graphics/GraphicBuffer;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/graphics/GraphicBuffer;->mNativeObject:J
-Landroid/graphics/ImageDecoder;->postProcessAndRelease(Landroid/graphics/Canvas;)I
-Landroid/graphics/ImageFormat;->Y8:I
-Landroid/graphics/LightingColorFilter;->setColorAdd(I)V
-Landroid/graphics/LightingColorFilter;->setColorMultiply(I)V
-Landroid/graphics/LinearGradient;->mColor0:I
-Landroid/graphics/LinearGradient;->mColor1:I
-Landroid/graphics/LinearGradient;->mColors:[I
-Landroid/graphics/LinearGradient;->mPositions:[F
-Landroid/graphics/LinearGradient;->mTileMode:Landroid/graphics/Shader$TileMode;
-Landroid/graphics/LinearGradient;->mX0:F
-Landroid/graphics/LinearGradient;->mX1:F
-Landroid/graphics/LinearGradient;->mY0:F
-Landroid/graphics/LinearGradient;->mY1:F
-Landroid/graphics/Matrix;->IDENTITY_MATRIX:Landroid/graphics/Matrix;
-Landroid/graphics/Matrix;->native_instance:J
-Landroid/graphics/Movie;-><init>(J)V
-Landroid/graphics/Movie;->mNativeMovie:J
-Landroid/graphics/NinePatch$InsetStruct;-><init>(IIIIIIIIFIF)V
-Landroid/graphics/NinePatch;->mBitmap:Landroid/graphics/Bitmap;
-Landroid/graphics/NinePatch;->mNativeChunk:J
-Landroid/graphics/Outline;->mRect:Landroid/graphics/Rect;
-Landroid/graphics/Paint;->getNativeInstance()J
-Landroid/graphics/Paint;->getTextRunAdvances([CIIIIZ[FI)F
-Landroid/graphics/Paint;->getTextRunCursor([CIIIII)I
-Landroid/graphics/Paint;->mNativePaint:J
-Landroid/graphics/Paint;->mTypeface:Landroid/graphics/Typeface;
-Landroid/graphics/Paint;->setCompatibilityScaling(F)V
-Landroid/graphics/Paint;->setHyphenEdit(I)V
-Landroid/graphics/Path;->isSimplePath:Z
-Landroid/graphics/Path;->rects:Landroid/graphics/Region;
-Landroid/graphics/pdf/PdfRenderer;->doClose()V
-Landroid/graphics/pdf/PdfRenderer;->mCurrentPage:Landroid/graphics/pdf/PdfRenderer$Page;
-Landroid/graphics/Picture;->mNativePicture:J
-Landroid/graphics/PorterDuff$Mode;->nativeInt:I
-Landroid/graphics/PorterDuffColorFilter;->getColor()I
-Landroid/graphics/PorterDuffColorFilter;->getMode()Landroid/graphics/PorterDuff$Mode;
-Landroid/graphics/RadialGradient;->mCenterColor:I
-Landroid/graphics/RadialGradient;->mColors:[I
-Landroid/graphics/RadialGradient;->mEdgeColor:I
-Landroid/graphics/RadialGradient;->mPositions:[F
-Landroid/graphics/RadialGradient;->mRadius:F
-Landroid/graphics/RadialGradient;->mTileMode:Landroid/graphics/Shader$TileMode;
-Landroid/graphics/RadialGradient;->mX:F
-Landroid/graphics/RadialGradient;->mY:F
-Landroid/graphics/Rect;->printShortString(Ljava/io/PrintWriter;)V
-Landroid/graphics/Rect;->scale(F)V
-Landroid/graphics/Region$Op;->nativeInt:I
-Landroid/graphics/Region;-><init>(JI)V
-Landroid/graphics/Region;->mNativeRegion:J
-Landroid/graphics/Region;->recycle()V
-Landroid/graphics/Region;->scale(F)V
-Landroid/graphics/Shader$TileMode;->nativeInt:I
-Landroid/graphics/SurfaceTexture;->mFrameAvailableListener:J
-Landroid/graphics/SurfaceTexture;->mOnFrameAvailableHandler:Landroid/os/Handler;
-Landroid/graphics/SurfaceTexture;->mProducer:J
-Landroid/graphics/SurfaceTexture;->mSurfaceTexture:J
-Landroid/graphics/SurfaceTexture;->nativeDetachFromGLContext()I
-Landroid/graphics/SurfaceTexture;->postEventFromNative(Ljava/lang/ref/WeakReference;)V
-Landroid/graphics/SweepGradient;->mColor0:I
-Landroid/graphics/SweepGradient;->mColor1:I
-Landroid/graphics/SweepGradient;->mColors:[I
-Landroid/graphics/SweepGradient;->mCx:F
-Landroid/graphics/SweepGradient;->mCy:F
-Landroid/graphics/SweepGradient;->mPositions:[F
-Landroid/graphics/TableMaskFilter;->CreateClipTable(II)Landroid/graphics/TableMaskFilter;
-Landroid/graphics/TemporaryBuffer;->obtain(I)[C
-Landroid/graphics/TemporaryBuffer;->recycle([C)V
-Landroid/graphics/Typeface;-><init>(J)V
-Landroid/graphics/Typeface;->createFromFamilies([Landroid/graphics/FontFamily;)Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->createFromFamiliesWithDefault([Landroid/graphics/FontFamily;II)Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->createFromFamiliesWithDefault([Landroid/graphics/FontFamily;Ljava/lang/String;II)Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->mStyle:I
-Landroid/graphics/Typeface;->nativeCreateFromArray([JII)J
-Landroid/graphics/Typeface;->nativeCreateWeightAlias(JI)J
-Landroid/graphics/Typeface;->native_instance:J
-Landroid/graphics/Typeface;->sDefaults:[Landroid/graphics/Typeface;
-Landroid/graphics/Typeface;->setDefault(Landroid/graphics/Typeface;)V
-Landroid/graphics/Typeface;->sSystemFallbackMap:Ljava/util/Map;
-Landroid/graphics/Typeface;->sSystemFontMap:Ljava/util/Map;
-Landroid/graphics/Xfermode;->porterDuffMode:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_GOOD:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_IMAGER_DIRTY:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_INSUFFICIENT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_PARTIAL:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_TOO_FAST:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ACQUIRED_TOO_SLOW:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_CANCELED:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_HW_NOT_PRESENT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_HW_UNAVAILABLE:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_LOCKOUT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_LOCKOUT_PERMANENT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_NO_BIOMETRICS:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_NO_SPACE:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_TIMEOUT:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_UNABLE_TO_PROCESS:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_USER_CANCELED:I
-Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_VENDOR:I
Landroid/hardware/biometrics/BiometricConstants;->BIOMETRIC_ERROR_VENDOR_BASE:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_GOOD:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_IMAGER_DIRTY:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_INSUFFICIENT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_PARTIAL:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_TOO_FAST:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ACQUIRED_TOO_SLOW:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_CANCELED:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_HW_NOT_PRESENT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_HW_UNAVAILABLE:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_LOCKOUT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_LOCKOUT_PERMANENT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_NO_FINGERPRINTS:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_NO_SPACE:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_TIMEOUT:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_UNABLE_TO_PROCESS:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_USER_CANCELED:I
-Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_VENDOR:I
Landroid/hardware/biometrics/BiometricFingerprintConstants;->FINGERPRINT_ERROR_VENDOR_BASE:I
Landroid/hardware/Camera$Parameters;->copyFrom(Landroid/hardware/Camera$Parameters;)V
Landroid/hardware/Camera$Parameters;->dump()V
@@ -2615,7 +2347,6 @@
Landroid/icu/text/Transliterator;->transliterate(Landroid/icu/text/Replaceable;Landroid/icu/text/Transliterator$Position;Ljava/lang/String;)V
Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String;
Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/UForwardCharacterIterator;->DONE:I
Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
Landroid/icu/util/PersianCalendar;-><init>(Ljava/util/Locale;)V
Landroid/icu/util/UResourceBundle;->getBundleInstance(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/util/UResourceBundle;
@@ -2624,26 +2355,6 @@
Landroid/icu/util/UResourceBundle;->getType()I
Landroid/icu/util/UResourceBundleIterator;->hasNext()Z
Landroid/icu/util/UResourceBundleIterator;->next()Landroid/icu/util/UResourceBundle;
-Landroid/inputmethodservice/InputMethodService$SettingsObserver;->shouldShowImeWithHardKeyboard()Z
-Landroid/inputmethodservice/InputMethodService;->mExtractEditText:Landroid/inputmethodservice/ExtractEditText;
-Landroid/inputmethodservice/InputMethodService;->mExtractView:Landroid/view/View;
-Landroid/inputmethodservice/InputMethodService;->mRootView:Landroid/view/View;
-Landroid/inputmethodservice/InputMethodService;->mSettingsObserver:Landroid/inputmethodservice/InputMethodService$SettingsObserver;
-Landroid/inputmethodservice/InputMethodService;->mTheme:I
-Landroid/inputmethodservice/InputMethodService;->mTmpInsets:Landroid/inputmethodservice/InputMethodService$Insets;
-Landroid/inputmethodservice/InputMethodService;->onExtractedDeleteText(II)V
-Landroid/inputmethodservice/InputMethodService;->onExtractedReplaceText(IILjava/lang/CharSequence;)V
-Landroid/inputmethodservice/InputMethodService;->onExtractedSetSpan(Ljava/lang/Object;III)V
-Landroid/inputmethodservice/Keyboard;->mModifierKeys:Ljava/util/List;
-Landroid/inputmethodservice/Keyboard;->mTotalHeight:I
-Landroid/inputmethodservice/Keyboard;->mTotalWidth:I
-Landroid/inputmethodservice/Keyboard;->resize(II)V
-Landroid/inputmethodservice/KeyboardView;->mKeyBackground:Landroid/graphics/drawable/Drawable;
-Landroid/inputmethodservice/KeyboardView;->mLabelTextSize:I
-Landroid/inputmethodservice/KeyboardView;->mPreviewText:Landroid/widget/TextView;
-Landroid/inputmethodservice/KeyboardView;->openPopupIfRequired(Landroid/view/MotionEvent;)Z
-Landroid/inputmethodservice/KeyboardView;->repeatKey()Z
-Landroid/inputmethodservice/KeyboardView;->showKey(I)V
Landroid/location/Country;-><init>(Ljava/lang/String;I)V
Landroid/location/Country;->getCountryIso()Ljava/lang/String;
Landroid/location/Country;->getSource()I
@@ -3143,81 +2854,6 @@
Landroid/media/TimedText;->getObject(I)Ljava/lang/Object;
Landroid/media/ToneGenerator;->mNativeContext:J
Landroid/media/TtmlRenderer;-><init>(Landroid/content/Context;)V
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_16_9:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_1_1:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_2_3:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_3_2:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->ASPECT_RATIO_4_3:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->AVAILABILITY_AVAILABLE:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->AVAILABILITY_FREE_WITH_SUBSCRIPTION:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->AVAILABILITY_PAID_CONTENT:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_AUTHOR:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_AVAILABILITY:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_BROWSABLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_CONTENT_ID:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_DURATION_MILLIS:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTENT_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTERACTION_COUNT:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTERACTION_TYPE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_INTERNAL_PROVIDER_ID:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_ITEM_COUNT:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_LAST_PLAYBACK_POSITION_MILLIS:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_LIVE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_LOGO_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_OFFER_PRICE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_POSTER_ART_ASPECT_RATIO:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_PREVIEW_VIDEO_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_RELEASE_DATE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_STARTING_PRICE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_THUMBNAIL_ASPECT_RATIO:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_TRANSIENT:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->COLUMN_TYPE:Ljava/lang/String;
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_FANS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_FOLLOWERS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_LIKES:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_LISTENS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_THUMBS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_VIEWERS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->INTERACTION_TYPE_VIEWS:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_ALBUM:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_ARTIST:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_CHANNEL:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_CLIP:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_EVENT:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_MOVIE:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_PLAYLIST:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_STATION:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TRACK:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TV_EPISODE:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TV_SEASON:I
-Landroid/media/tv/TvContract$PreviewProgramColumns;->TYPE_TV_SERIES:I
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_AUDIO_LANGUAGE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_CANONICAL_GENRE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_CONTENT_RATING:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_EPISODE_DISPLAY_NUMBER:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_EPISODE_TITLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_DATA:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG1:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG2:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG3:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_INTERNAL_PROVIDER_FLAG4:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_LONG_DESCRIPTION:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_POSTER_ART_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_REVIEW_RATING:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_REVIEW_RATING_STYLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SEARCHABLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SEASON_DISPLAY_NUMBER:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SEASON_TITLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SERIES_ID:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_SHORT_DESCRIPTION:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_THUMBNAIL_URI:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_TITLE:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_VERSION_NUMBER:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_VIDEO_HEIGHT:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->COLUMN_VIDEO_WIDTH:Ljava/lang/String;
-Landroid/media/tv/TvContract$ProgramColumns;->REVIEW_RATING_STYLE_PERCENTAGE:I
-Landroid/media/tv/TvContract$ProgramColumns;->REVIEW_RATING_STYLE_STARS:I
-Landroid/media/tv/TvContract$ProgramColumns;->REVIEW_RATING_STYLE_THUMBS_UP_DOWN:I
Landroid/media/tv/TvInputInfo;->getComponent()Landroid/content/ComponentName;
Landroid/media/tv/TvInputService$Session;->mOverlayFrame:Landroid/graphics/Rect;
Landroid/media/VolumeShaper$Configuration;-><init>(IIIDI[F[F)V
@@ -3709,28 +3345,6 @@
Landroid/net/wifi/WifiSsid;->getOctets()[B
Landroid/net/wifi/WifiSsid;->NONE:Ljava/lang/String;
Landroid/net/wifi/WifiSsid;->octets:Ljava/io/ByteArrayOutputStream;
-Landroid/nfc/cardemulation/AidGroup;-><init>(Ljava/lang/String;Ljava/lang/String;)V
-Landroid/nfc/cardemulation/AidGroup;->aids:Ljava/util/List;
-Landroid/nfc/cardemulation/AidGroup;->category:Ljava/lang/String;
-Landroid/nfc/cardemulation/AidGroup;->createFromXml(Lorg/xmlpull/v1/XmlPullParser;)Landroid/nfc/cardemulation/AidGroup;
-Landroid/nfc/cardemulation/AidGroup;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/nfc/cardemulation/AidGroup;->description:Ljava/lang/String;
-Landroid/nfc/cardemulation/AidGroup;->getAids()Ljava/util/List;
-Landroid/nfc/cardemulation/AidGroup;->getCategory()Ljava/lang/String;
-Landroid/nfc/cardemulation/AidGroup;->writeAsXml(Lorg/xmlpull/v1/XmlSerializer;)V
-Landroid/nfc/cardemulation/ApduServiceInfo;-><init>(Landroid/content/pm/PackageManager;Landroid/content/pm/ResolveInfo;Z)V
-Landroid/nfc/cardemulation/ApduServiceInfo;-><init>(Landroid/content/pm/ResolveInfo;ZLjava/lang/String;Ljava/util/ArrayList;Ljava/util/ArrayList;ZIILjava/lang/String;)V
-Landroid/nfc/cardemulation/ApduServiceInfo;->CREATOR:Landroid/os/Parcelable$Creator;
-Landroid/nfc/cardemulation/ApduServiceInfo;->getDescription()Ljava/lang/String;
-Landroid/nfc/cardemulation/ApduServiceInfo;->getSettingsActivityName()Ljava/lang/String;
-Landroid/nfc/cardemulation/ApduServiceInfo;->getUid()I
-Landroid/nfc/cardemulation/ApduServiceInfo;->isOnHost()Z
-Landroid/nfc/cardemulation/ApduServiceInfo;->loadBanner(Landroid/content/pm/PackageManager;)Landroid/graphics/drawable/Drawable;
-Landroid/nfc/cardemulation/ApduServiceInfo;->mDynamicAidGroups:Ljava/util/HashMap;
-Landroid/nfc/cardemulation/ApduServiceInfo;->mService:Landroid/content/pm/ResolveInfo;
-Landroid/nfc/cardemulation/ApduServiceInfo;->mStaticAidGroups:Ljava/util/HashMap;
-Landroid/nfc/cardemulation/ApduServiceInfo;->requiresUnlock()Z
-Landroid/nfc/ErrorCodes;->isError(I)Z
Landroid/nfc/INfcAdapter$Stub;->TRANSACTION_enable:I
Landroid/nfc/INfcAdapterExtras;->authenticate(Ljava/lang/String;[B)V
Landroid/nfc/INfcAdapterExtras;->close(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle;
@@ -3739,21 +3353,6 @@
Landroid/nfc/INfcAdapterExtras;->open(Ljava/lang/String;Landroid/os/IBinder;)Landroid/os/Bundle;
Landroid/nfc/INfcAdapterExtras;->setCardEmulationRoute(Ljava/lang/String;I)V
Landroid/nfc/INfcAdapterExtras;->transceive(Ljava/lang/String;[B)Landroid/os/Bundle;
-Landroid/nfc/NdefRecord;->mId:[B
-Landroid/nfc/NfcActivityManager;->mAdapter:Landroid/nfc/NfcAdapter;
-Landroid/nfc/NfcAdapter;->attemptDeadServiceRecovery(Ljava/lang/Exception;)V
-Landroid/nfc/NfcAdapter;->getAdapterState()I
-Landroid/nfc/NfcAdapter;->getContext()Landroid/content/Context;
-Landroid/nfc/NfcAdapter;->getDefaultAdapter()Landroid/nfc/NfcAdapter;
-Landroid/nfc/NfcAdapter;->getNfcAdapter(Landroid/content/Context;)Landroid/nfc/NfcAdapter;
-Landroid/nfc/NfcAdapter;->getNfcAdapterExtrasInterface()Landroid/nfc/INfcAdapterExtras;
-Landroid/nfc/NfcAdapter;->getService()Landroid/nfc/INfcAdapter;
-Landroid/nfc/NfcAdapter;->setNdefPushMessageCallback(Landroid/nfc/NfcAdapter$CreateNdefMessageCallback;Landroid/app/Activity;I)V
-Landroid/nfc/NfcAdapter;->sService:Landroid/nfc/INfcAdapter;
-Landroid/nfc/NfcManager;-><init>(Landroid/content/Context;)V
-Landroid/nfc/Tag;->getServiceHandle()I
-Landroid/nfc/Tag;->getTagService()Landroid/nfc/INfcTag;
-Landroid/nfc/Tag;->mId:[B
Landroid/opengl/EGL14;->eglGetDisplay(J)Landroid/opengl/EGLDisplay;
Landroid/opengl/GLES20;->glGetActiveAttrib(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;B)V
Landroid/opengl/GLES20;->glGetActiveUniform(IIILjava/nio/IntBuffer;Ljava/nio/IntBuffer;Ljava/nio/IntBuffer;B)V
@@ -4431,10 +4030,6 @@
Landroid/preference/VolumePreference$VolumeStore;->volume:I
Landroid/preference/VolumePreference;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
Landroid/preference/VolumePreference;->mStreamType:I
-Landroid/print/PrinterId;->getServiceName()Landroid/content/ComponentName;
-Landroid/print/PrintJobInfo;->getAdvancedOptions()Landroid/os/Bundle;
-Landroid/print/PrintJobInfo;->getDocumentInfo()Landroid/print/PrintDocumentInfo;
-Landroid/print/PrintManager;->addPrintJobStateChangeListener(Landroid/print/PrintManager$PrintJobStateChangeListener;)V
Landroid/provider/Browser;->getVisitedHistory(Landroid/content/ContentResolver;)[Ljava/lang/String;
Landroid/provider/Browser;->sendString(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V
Landroid/provider/BrowserContract$Accounts;->CONTENT_URI:Landroid/net/Uri;
@@ -4449,9 +4044,6 @@
Landroid/provider/CalendarContract$CalendarAlerts;->rescheduleMissedAlarms(Landroid/content/ContentResolver;Landroid/content/Context;Landroid/app/AlarmManager;)V
Landroid/provider/CalendarContract$CalendarAlerts;->scheduleAlarm(Landroid/content/Context;Landroid/app/AlarmManager;J)V
Landroid/provider/CallLog$Calls;->addCall(Lcom/android/internal/telephony/CallerInfo;Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IIILandroid/telecom/PhoneAccountHandle;JILjava/lang/Long;ZLandroid/os/UserHandle;Z)Landroid/net/Uri;
-Landroid/provider/ContactsContract$ContactCounts;->EXTRA_ADDRESS_BOOK_INDEX:Ljava/lang/String;
-Landroid/provider/ContactsContract$ContactCounts;->EXTRA_ADDRESS_BOOK_INDEX_COUNTS:Ljava/lang/String;
-Landroid/provider/ContactsContract$ContactCounts;->EXTRA_ADDRESS_BOOK_INDEX_TITLES:Ljava/lang/String;
Landroid/provider/ContactsContract$Contacts$AggregationSuggestions;->builder()Landroid/provider/ContactsContract$Contacts$AggregationSuggestions$Builder;
Landroid/provider/ContactsContract$Contacts;->CORP_CONTENT_URI:Landroid/net/Uri;
Landroid/provider/ContactsContract$QuickContact;->composeQuickContactsIntent(Landroid/content/Context;Landroid/graphics/Rect;Landroid/net/Uri;I[Ljava/lang/String;)Landroid/content/Intent;
@@ -4975,7 +4567,7 @@
Landroid/renderscript/RSSurfaceView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
Landroid/renderscript/Script$Builder;-><init>(Landroid/renderscript/RenderScript;)V
Landroid/renderscript/Script$Builder;->mRS:Landroid/renderscript/RenderScript;
-Landroid/security/Credentials;->convertToPem([[Ljava/security/cert/Certificate;)[B
+Landroid/security/Credentials;->convertToPem([Ljava/security/cert/Certificate;)[B
Landroid/security/Credentials;->getInstance()Landroid/security/Credentials;
Landroid/security/Credentials;->install(Landroid/content/Context;Ljava/lang/String;[B)V
Landroid/security/Credentials;->install(Landroid/content/Context;Ljava/security/KeyPair;)V
@@ -5842,21 +5434,6 @@
Landroid/view/AccessibilityIterators$AbstractTextSegmentIterator;->mText:Ljava/lang/String;
Landroid/view/ActionProvider;->reset()V
Landroid/view/ActionProvider;->setSubUiVisibilityListener(Landroid/view/ActionProvider$SubUiVisibilityListener;)V
-Landroid/view/animation/Animation;->detach()V
-Landroid/view/animation/Animation;->getInvalidateRegion(IIIILandroid/graphics/RectF;Landroid/view/animation/Transformation;)V
-Landroid/view/animation/Animation;->initializeInvalidateRegion(IIII)V
-Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener;
-Landroid/view/animation/Animation;->mPreviousRegion:Landroid/graphics/RectF;
-Landroid/view/animation/Animation;->mPreviousTransformation:Landroid/view/animation/Transformation;
-Landroid/view/animation/Animation;->mRegion:Landroid/graphics/RectF;
-Landroid/view/animation/Animation;->mTransformation:Landroid/view/animation/Transformation;
-Landroid/view/animation/AnimationUtils;->createAnimationFromXml(Landroid/content/Context;Lorg/xmlpull/v1/XmlPullParser;Landroid/view/animation/AnimationSet;Landroid/util/AttributeSet;)Landroid/view/animation/Animation;
-Landroid/view/animation/Transformation;->printShortString(Ljava/io/PrintWriter;)V
-Landroid/view/animation/TranslateAnimation;->mFromXValue:F
-Landroid/view/animation/TranslateAnimation;->mFromYValue:F
-Landroid/view/animation/TranslateAnimation;->mToXValue:F
-Landroid/view/animation/TranslateAnimation;->mToYValue:F
-Landroid/view/animation/TranslateYAnimation;-><init>(IFIF)V
Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/view/autofill/IAutoFillManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/autofill/IAutoFillManager;
Landroid/view/Choreographer$CallbackQueue;->addCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)V
@@ -6653,7 +6230,6 @@
Landroid/webkit/WebResourceResponse;->mImmutable:Z
Landroid/webkit/WebResourceResponse;->mStatusCode:I
Landroid/webkit/WebSettings$TextSize;->value:I
-Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler;
Landroid/webkit/WebSyncManager;->syncFromRamToFlash()V
Landroid/webkit/WebView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;IILjava/util/Map;Z)V
Landroid/webkit/WebView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;ILjava/util/Map;Z)V
@@ -7326,73 +6902,6 @@
Lcom/android/ims/internal/IImsVideoCallCallback;->receiveSessionModifyResponse(ILandroid/telecom/VideoProfile;Landroid/telecom/VideoProfile;)V
Lcom/android/ims/internal/IImsVideoCallProvider$Stub;-><init>()V
Lcom/android/ims/internal/IImsVideoCallProvider;->setCallback(Lcom/android/ims/internal/IImsVideoCallCallback;)V
-Lcom/android/ims/internal/uce/common/CapInfo;-><init>()V
-Lcom/android/ims/internal/uce/common/CapInfo;->setCapTimestamp(J)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setCdViaPresenceSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setExts([Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtHttpSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtSnFSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFtThumbSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setFullSnFGroupChatSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setGeoPullFtSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setGeoPullSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setGeoPushSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setImSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setIpVideoSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setIpVoiceSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setIsSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setRcsIpVideoCallSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setRcsIpVideoOnlyCallSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setRcsIpVoiceCallSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setSmSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setSpSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setVsDuringCSSupported(Z)V
-Lcom/android/ims/internal/uce/common/CapInfo;->setVsSupported(Z)V
-Lcom/android/ims/internal/uce/common/StatusCode;-><init>()V
-Lcom/android/ims/internal/uce/common/StatusCode;->setStatusCode(I)V
-Lcom/android/ims/internal/uce/common/UceLong;->getUceLong()J
-Lcom/android/ims/internal/uce/common/UceLong;->setUceLong(J)V
-Lcom/android/ims/internal/uce/presence/PresCmdId;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresCmdId;->setCmdId(I)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setCmdId(Lcom/android/ims/internal/uce/presence/PresCmdId;)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setRequestId(I)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setStatus(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/presence/PresCmdStatus;->setUserData(I)V
-Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresPublishTriggerType;->setPublishTrigeerType(I)V
-Lcom/android/ims/internal/uce/presence/PresResInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresResInfo;->setDisplayName(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInfo;->setInstanceInfo(Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;)V
-Lcom/android/ims/internal/uce/presence/PresResInfo;->setResUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setPresentityUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setReason(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setResId(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setResInstanceState(I)V
-Lcom/android/ims/internal/uce/presence/PresResInstanceInfo;->setTupleInfo([Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setFullState(Z)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setListName(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setPresSubscriptionState(Lcom/android/ims/internal/uce/presence/PresSubscriptionState;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setRequestId(I)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setSubscriptionExpireTime(I)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setSubscriptionTerminatedReason(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresRlmiInfo;->setVersion(I)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setCmdId(Lcom/android/ims/internal/uce/presence/PresCmdId;)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setReasonPhrase(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setRequestId(I)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setRetryAfter(I)V
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->setSipResponseCode(I)V
-Lcom/android/ims/internal/uce/presence/PresSubscriptionState;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresSubscriptionState;->setPresSubscriptionState(I)V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;-><init>()V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setContactUri(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setFeatureTag(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setTimestamp(Ljava/lang/String;)V
Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
Lcom/android/internal/app/AlertController$AlertParams;-><init>(Landroid/content/Context;)V
Lcom/android/internal/app/AlertController$AlertParams;->apply(Lcom/android/internal/app/AlertController;)V
@@ -8355,6 +7864,7 @@
Lcom/android/internal/util/AsyncChannel;->sendMessageSynchronously(Landroid/os/Message;)Landroid/os/Message;
Lcom/android/internal/util/AsyncChannel;->STATUS_SUCCESSFUL:I
Lcom/android/internal/util/FastPrintWriter;-><init>(Ljava/io/OutputStream;)V
+Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String;
Lcom/android/internal/util/XmlUtils;->convertValueToBoolean(Ljava/lang/CharSequence;Z)Z
Lcom/android/internal/util/XmlUtils;->convertValueToInt(Ljava/lang/CharSequence;I)I
Lcom/android/internal/util/XmlUtils;->readMapXml(Ljava/io/InputStream;)Ljava/util/HashMap;
@@ -8444,6 +7954,7 @@
Lcom/android/internal/widget/IRemoteViewsFactory;->hasStableIds()Z
Lcom/android/internal/widget/IRemoteViewsFactory;->isCreated()Z
Lcom/android/internal/widget/IRemoteViewsFactory;->onDataSetChanged()V
+Lcom/android/internal/widget/ScrollBarUtils;->getThumbLength(IIII)I
Lcom/android/internal/widget/ScrollingTabContainerView;-><init>(Landroid/content/Context;)V
Lcom/android/internal/widget/ScrollingTabContainerView;->addTab(Landroid/app/ActionBar$Tab;IZ)V
Lcom/android/internal/widget/ScrollingTabContainerView;->addTab(Landroid/app/ActionBar$Tab;Z)V
@@ -8515,6 +8026,8 @@
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setNpnProtocols([B)V
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setSoWriteTimeout(I)V
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V
+Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setHostname(Ljava/lang/String;)V
+Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setUseSessionTickets(Z)V
Lcom/android/org/conscrypt/ConscryptSocketBase;->getHostname()Ljava/lang/String;
Lcom/android/org/conscrypt/ConscryptSocketBase;->getHostnameOrIP()Ljava/lang/String;
Lcom/android/org/conscrypt/ConscryptSocketBase;->getSoWriteTimeout()I
@@ -8984,46 +8497,6 @@
Ljava/util/zip/Inflater;->len:I
Ljava/util/zip/Inflater;->needDict:Z
Ljava/util/zip/Inflater;->off:I
-Ljava/util/zip/ZipConstants;->CENATT:I
-Ljava/util/zip/ZipConstants;->CENATX:I
-Ljava/util/zip/ZipConstants;->CENCOM:I
-Ljava/util/zip/ZipConstants;->CENCRC:I
-Ljava/util/zip/ZipConstants;->CENDSK:I
-Ljava/util/zip/ZipConstants;->CENEXT:I
-Ljava/util/zip/ZipConstants;->CENFLG:I
-Ljava/util/zip/ZipConstants;->CENHDR:I
-Ljava/util/zip/ZipConstants;->CENHOW:I
-Ljava/util/zip/ZipConstants;->CENLEN:I
-Ljava/util/zip/ZipConstants;->CENNAM:I
-Ljava/util/zip/ZipConstants;->CENOFF:I
-Ljava/util/zip/ZipConstants;->CENSIG:J
-Ljava/util/zip/ZipConstants;->CENSIZ:I
-Ljava/util/zip/ZipConstants;->CENTIM:I
-Ljava/util/zip/ZipConstants;->CENVEM:I
-Ljava/util/zip/ZipConstants;->CENVER:I
-Ljava/util/zip/ZipConstants;->ENDCOM:I
-Ljava/util/zip/ZipConstants;->ENDHDR:I
-Ljava/util/zip/ZipConstants;->ENDOFF:I
-Ljava/util/zip/ZipConstants;->ENDSIG:J
-Ljava/util/zip/ZipConstants;->ENDSIZ:I
-Ljava/util/zip/ZipConstants;->ENDSUB:I
-Ljava/util/zip/ZipConstants;->ENDTOT:I
-Ljava/util/zip/ZipConstants;->EXTCRC:I
-Ljava/util/zip/ZipConstants;->EXTHDR:I
-Ljava/util/zip/ZipConstants;->EXTLEN:I
-Ljava/util/zip/ZipConstants;->EXTSIG:J
-Ljava/util/zip/ZipConstants;->EXTSIZ:I
-Ljava/util/zip/ZipConstants;->LOCCRC:I
-Ljava/util/zip/ZipConstants;->LOCEXT:I
-Ljava/util/zip/ZipConstants;->LOCFLG:I
-Ljava/util/zip/ZipConstants;->LOCHDR:I
-Ljava/util/zip/ZipConstants;->LOCHOW:I
-Ljava/util/zip/ZipConstants;->LOCLEN:I
-Ljava/util/zip/ZipConstants;->LOCNAM:I
-Ljava/util/zip/ZipConstants;->LOCSIG:J
-Ljava/util/zip/ZipConstants;->LOCSIZ:I
-Ljava/util/zip/ZipConstants;->LOCTIM:I
-Ljava/util/zip/ZipConstants;->LOCVER:I
Ljava/util/zip/ZipEntry;-><init>(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V
Ljava/util/zip/ZipEntry;->method:I
Ljava/util/zip/ZipFile;->close(J)V
@@ -9038,6 +8511,16 @@
Ljavax/net/ssl/SSLServerSocketFactory;->defaultServerSocketFactory:Ljavax/net/ssl/SSLServerSocketFactory;
Ljavax/net/ssl/SSLSocketFactory;->createSocket(Ljava/net/Socket;Ljava/io/InputStream;Z)Ljava/net/Socket;
Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
+Llibcore/icu/ICU;->addLikelySubtags(Ljava/util/Locale;)Ljava/util/Locale;
+Llibcore/io/Memory;->peekByte(J)B
+Llibcore/io/Memory;->peekByteArray(J[BII)V
+Llibcore/io/Memory;->peekInt(JZ)I
+Llibcore/io/Memory;->peekLong(JZ)J
+Llibcore/io/Memory;->pokeByte(JB)V
+Llibcore/io/Memory;->pokeByteArray(J[BII)V
+Llibcore/io/Memory;->pokeInt(JIZ)V
+Llibcore/io/Memory;->pokeLong(JJZ)V
+Llibcore/io/Streams;->copy(Ljava/io/InputStream;Ljava/io/OutputStream;)I
Llibcore/util/BasicLruCache;->map:Ljava/util/LinkedHashMap;
Llibcore/util/ZoneInfo;->mTransitions:[J
Lorg/apache/http/conn/ssl/AbstractVerifier;->BAD_COUNTRY_2LDS:[Ljava/lang/String;
@@ -9060,6 +8543,8 @@
Lorg/ccil/cowan/tagsoup/ElementType;->theNamespace:Ljava/lang/String;
Lorg/ccil/cowan/tagsoup/ElementType;->theParent:Lorg/ccil/cowan/tagsoup/ElementType;
Lorg/ccil/cowan/tagsoup/ElementType;->theSchema:Lorg/ccil/cowan/tagsoup/Schema;
+Lorg/ccil/cowan/tagsoup/HTMLSchema;-><init>()V
+Lorg/ccil/cowan/tagsoup/Parser;-><init>()V
Lorg/ccil/cowan/tagsoup/Schema;->theElementTypes:Ljava/util/HashMap;
Lorg/ccil/cowan/tagsoup/Schema;->theEntities:Ljava/util/HashMap;
Lorg/ccil/cowan/tagsoup/Schema;->thePrefix:Ljava/lang/String;
@@ -9159,10 +8644,84 @@
Lorg/xml/sax/SAXParseException;->lineNumber:I
Lorg/xml/sax/SAXParseException;->publicId:Ljava/lang/String;
Lorg/xml/sax/SAXParseException;->systemId:Ljava/lang/String;
+Lsun/misc/Cleaner;->clean()V
+Lsun/misc/Unsafe;->addressSize()I
+Lsun/misc/Unsafe;->allocateInstance(Ljava/lang/Class;)Ljava/lang/Object;
+Lsun/misc/Unsafe;->allocateMemory(J)J
+Lsun/misc/Unsafe;->arrayBaseOffset(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->arrayIndexScale(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->compareAndSwapInt(Ljava/lang/Object;JII)Z
+Lsun/misc/Unsafe;->compareAndSwapLong(Ljava/lang/Object;JJJ)Z
+Lsun/misc/Unsafe;->compareAndSwapObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
+Lsun/misc/Unsafe;->copyMemory(JJJ)V
+Lsun/misc/Unsafe;->copyMemoryFromPrimitiveArray(Ljava/lang/Object;JJJ)V
+Lsun/misc/Unsafe;->copyMemoryToPrimitiveArray(JLjava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->freeMemory(J)V
+Lsun/misc/Unsafe;->fullFence()V
+Lsun/misc/Unsafe;->getAndAddInt(Ljava/lang/Object;JI)I
+Lsun/misc/Unsafe;->getAndAddLong(Ljava/lang/Object;JJ)J
+Lsun/misc/Unsafe;->getAndSetInt(Ljava/lang/Object;JI)I
+Lsun/misc/Unsafe;->getAndSetLong(Ljava/lang/Object;JJ)J
+Lsun/misc/Unsafe;->getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;
+Lsun/misc/Unsafe;->getArrayBaseOffsetForComponentType(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->getArrayIndexScaleForComponentType(Ljava/lang/Class;)I
+Lsun/misc/Unsafe;->getBoolean(Ljava/lang/Object;J)Z
+Lsun/misc/Unsafe;->getByte(J)B
+Lsun/misc/Unsafe;->getByte(Ljava/lang/Object;J)B
+Lsun/misc/Unsafe;->getChar(J)C
+Lsun/misc/Unsafe;->getChar(Ljava/lang/Object;J)C
+Lsun/misc/Unsafe;->getDouble(J)D
+Lsun/misc/Unsafe;->getDouble(Ljava/lang/Object;J)D
+Lsun/misc/Unsafe;->getFloat(J)F
+Lsun/misc/Unsafe;->getFloat(Ljava/lang/Object;J)F
+Lsun/misc/Unsafe;->getInt(J)I
+Lsun/misc/Unsafe;->getInt(Ljava/lang/Object;J)I
+Lsun/misc/Unsafe;->getIntVolatile(Ljava/lang/Object;J)I
+Lsun/misc/Unsafe;->getLong(J)J
+Lsun/misc/Unsafe;->getLong(Ljava/lang/Object;J)J
+Lsun/misc/Unsafe;->getLongVolatile(Ljava/lang/Object;J)J
+Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object;
+Lsun/misc/Unsafe;->getObjectVolatile(Ljava/lang/Object;J)Ljava/lang/Object;
+Lsun/misc/Unsafe;->getShort(J)S
+Lsun/misc/Unsafe;->getShort(Ljava/lang/Object;J)S
+Lsun/misc/Unsafe;->getUnsafe()Lsun/misc/Unsafe;
+Lsun/misc/Unsafe;->INVALID_FIELD_OFFSET:I
+Lsun/misc/Unsafe;->loadFence()V
+Lsun/misc/Unsafe;->objectFieldOffset(Ljava/lang/reflect/Field;)J
+Lsun/misc/Unsafe;->pageSize()I
+Lsun/misc/Unsafe;->park(ZJ)V
+Lsun/misc/Unsafe;->putBoolean(Ljava/lang/Object;JZ)V
+Lsun/misc/Unsafe;->putByte(JB)V
+Lsun/misc/Unsafe;->putByte(Ljava/lang/Object;JB)V
+Lsun/misc/Unsafe;->putChar(JC)V
+Lsun/misc/Unsafe;->putChar(Ljava/lang/Object;JC)V
+Lsun/misc/Unsafe;->putDouble(JD)V
+Lsun/misc/Unsafe;->putDouble(Ljava/lang/Object;JD)V
+Lsun/misc/Unsafe;->putFloat(JF)V
+Lsun/misc/Unsafe;->putFloat(Ljava/lang/Object;JF)V
+Lsun/misc/Unsafe;->putInt(JI)V
+Lsun/misc/Unsafe;->putInt(Ljava/lang/Object;JI)V
+Lsun/misc/Unsafe;->putIntVolatile(Ljava/lang/Object;JI)V
+Lsun/misc/Unsafe;->putLong(JJ)V
+Lsun/misc/Unsafe;->putLong(Ljava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->putLongVolatile(Ljava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->putObject(Ljava/lang/Object;JLjava/lang/Object;)V
+Lsun/misc/Unsafe;->putObjectVolatile(Ljava/lang/Object;JLjava/lang/Object;)V
+Lsun/misc/Unsafe;->putOrderedInt(Ljava/lang/Object;JI)V
+Lsun/misc/Unsafe;->putOrderedLong(Ljava/lang/Object;JJ)V
+Lsun/misc/Unsafe;->putOrderedObject(Ljava/lang/Object;JLjava/lang/Object;)V
+Lsun/misc/Unsafe;->putShort(JS)V
+Lsun/misc/Unsafe;->putShort(Ljava/lang/Object;JS)V
+Lsun/misc/Unsafe;->setMemory(JJB)V
+Lsun/misc/Unsafe;->storeFence()V
Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe;
Lsun/misc/Unsafe;->THE_ONE:Lsun/misc/Unsafe;
+Lsun/misc/Unsafe;->unpark(Ljava/lang/Object;)V
Lsun/misc/URLClassPath$JarLoader;->getJarFile()Ljava/util/jar/JarFile;
Lsun/misc/URLClassPath;->lmap:Ljava/util/HashMap;
Lsun/misc/URLClassPath;->loaders:Ljava/util/ArrayList;
Lsun/misc/URLClassPath;->urls:Ljava/util/Stack;
+Lsun/nio/ch/DirectBuffer;->cleaner()Lsun/misc/Cleaner;
+Lsun/security/x509/AlgorithmId;->get(Ljava/lang/String;)Lsun/security/x509/AlgorithmId;
+Lsun/security/x509/AlgorithmId;->getName()Ljava/lang/String;
Lsun/security/x509/AVA;->hasRFC2253Keyword()Z
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index a07843b..b8c1468 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -93,10 +93,6 @@
Landroid/content/pm/IPackageStatsObserver;->onGetStatsCompleted(Landroid/content/pm/PackageStats;Z)V
Landroid/database/sqlite/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
Landroid/database/sqlite/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
-Landroid/graphics/Bitmap;->createGraphicBufferHandle()Landroid/graphics/GraphicBuffer;
-Landroid/graphics/Bitmap;->createHardwareBitmap(Landroid/graphics/GraphicBuffer;)Landroid/graphics/Bitmap;
-Landroid/graphics/drawable/Drawable;->isProjected()Z
-Landroid/graphics/drawable/Drawable;->updateTintFilter(Landroid/graphics/PorterDuffColorFilter;Landroid/content/res/ColorStateList;Landroid/graphics/PorterDuff$Mode;)Landroid/graphics/PorterDuffColorFilter;
Landroid/hardware/camera2/CaptureRequest$Key;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
Landroid/hardware/display/DisplayManagerGlobal;->getInstance()Landroid/hardware/display/DisplayManagerGlobal;
Landroid/hardware/display/DisplayManagerGlobal;->getRealDisplay(I)Landroid/view/Display;
@@ -370,8 +366,6 @@
Landroid/os/UserHandle;->isSameApp(II)Z
Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
Landroid/os/UserManager;->isAdminUser()Z
-Landroid/print/PrintDocumentAdapter$LayoutResultCallback;-><init>()V
-Landroid/print/PrintDocumentAdapter$WriteResultCallback;-><init>()V
Landroid/provider/CalendarContract$Events;->PROVIDER_WRITABLE_COLUMNS:[Ljava/lang/String;
Landroid/provider/ContactsContract$CommonDataKinds$Phone;->getDisplayLabel(Landroid/content/Context;ILjava/lang/CharSequence;)Ljava/lang/CharSequence;
Landroid/provider/Settings$Global;->getStringForUser(Landroid/content/ContentResolver;Ljava/lang/String;I)Ljava/lang/String;
@@ -611,31 +605,6 @@
Lcom/android/ims/internal/IImsUtListener;->utConfigurationQueryFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdated(Lcom/android/ims/internal/IImsUt;I)V
Lcom/android/ims/internal/IImsUtListener;->utConfigurationUpdateFailed(Lcom/android/ims/internal/IImsUt;ILandroid/telephony/ims/ImsReasonInfo;)V
-Lcom/android/ims/internal/uce/common/CapInfo;->getCapTimestamp()J
-Lcom/android/ims/internal/uce/common/CapInfo;->isCdViaPresenceSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtHttpSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtSnFSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFtThumbSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isFullSnFGroupChatSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isGeoPullFtSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isGeoPullSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isGeoPushSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isImSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isIpVideoSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isIpVoiceSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isIsSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isRcsIpVideoCallSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isRcsIpVideoOnlyCallSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isRcsIpVoiceCallSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isSmSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isSpSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isVsDuringCSSupported()Z
-Lcom/android/ims/internal/uce/common/CapInfo;->isVsSupported()Z
-Lcom/android/ims/internal/uce/common/StatusCode;->getStatusCode()I
-Lcom/android/ims/internal/uce/common/UceLong;-><init>()V
-Lcom/android/ims/internal/uce/common/UceLong;->getClientId()I
-Lcom/android/ims/internal/uce/common/UceLong;->setClientId(I)V
Lcom/android/ims/internal/uce/options/IOptionsListener;->cmdStatus(Lcom/android/ims/internal/uce/options/OptionsCmdStatus;)V
Lcom/android/ims/internal/uce/options/IOptionsListener;->getVersionCb(Ljava/lang/String;)V
Lcom/android/ims/internal/uce/options/IOptionsListener;->incomingOptions(Ljava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;I)V
@@ -651,24 +620,6 @@
Lcom/android/ims/internal/uce/options/IOptionsService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/options/IOptionsService;->responseIncomingOptions(IIILjava/lang/String;Lcom/android/ims/internal/uce/options/OptionsCapInfo;Z)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/options/IOptionsService;->setMyInfo(ILcom/android/ims/internal/uce/common/CapInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->getCapInfo()Lcom/android/ims/internal/uce/common/CapInfo;
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->getSdp()Ljava/lang/String;
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->setCapInfo(Lcom/android/ims/internal/uce/common/CapInfo;)V
-Lcom/android/ims/internal/uce/options/OptionsCapInfo;->setSdp(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdId;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsCmdId;->setCmdId(I)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setCapInfo(Lcom/android/ims/internal/uce/common/CapInfo;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setCmdId(Lcom/android/ims/internal/uce/options/OptionsCmdId;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setStatus(Lcom/android/ims/internal/uce/common/StatusCode;)V
-Lcom/android/ims/internal/uce/options/OptionsCmdStatus;->setUserData(I)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;-><init>()V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setCmdId(Lcom/android/ims/internal/uce/options/OptionsCmdId;)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setReasonPhrase(Ljava/lang/String;)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setRequestId(I)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setRetryAfter(I)V
-Lcom/android/ims/internal/uce/options/OptionsSipResponse;->setSipResponseCode(I)V
Lcom/android/ims/internal/uce/presence/IPresenceListener;->capInfoReceived(Ljava/lang/String;[Lcom/android/ims/internal/uce/presence/PresTupleInfo;)V
Lcom/android/ims/internal/uce/presence/IPresenceListener;->cmdStatus(Lcom/android/ims/internal/uce/presence/PresCmdStatus;)V
Lcom/android/ims/internal/uce/presence/IPresenceListener;->getVersionCb(Ljava/lang/String;)V
@@ -687,18 +638,6 @@
Lcom/android/ims/internal/uce/presence/IPresenceService;->reenableService(II)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/presence/IPresenceService;->removeListener(ILcom/android/ims/internal/uce/common/UceLong;)Lcom/android/ims/internal/uce/common/StatusCode;
Lcom/android/ims/internal/uce/presence/IPresenceService;->setNewFeatureTag(ILjava/lang/String;Lcom/android/ims/internal/uce/presence/PresServiceInfo;I)Lcom/android/ims/internal/uce/common/StatusCode;
-Lcom/android/ims/internal/uce/presence/PresCapInfo;->getCapInfo()Lcom/android/ims/internal/uce/common/CapInfo;
-Lcom/android/ims/internal/uce/presence/PresCapInfo;->getContactUri()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresCapInfo;->mContactUri:Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getMediaType()I
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceDesc()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceId()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresServiceInfo;->getServiceVer()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getCmdId()Lcom/android/ims/internal/uce/presence/PresCmdId;
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getReasonPhrase()Ljava/lang/String;
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getRequestId()I
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getRetryAfter()I
-Lcom/android/ims/internal/uce/presence/PresSipResponse;->getSipResponseCode()I
Lcom/android/ims/internal/uce/uceservice/IUceListener;->setStatus(I)V
Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
Lcom/android/ims/internal/uce/uceservice/IUceService;->createOptionsService(Lcom/android/ims/internal/uce/options/IOptionsListener;Lcom/android/ims/internal/uce/common/UceLong;)I
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 829a9444..5b73eaa 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
+import android.annotation.UnsupportedAppUsage;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
@@ -31,7 +32,6 @@
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
-import android.provider.Settings;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
@@ -398,17 +398,55 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = { "SHOW_MODE_" }, value = {
SHOW_MODE_AUTO,
- SHOW_MODE_HIDDEN
+ SHOW_MODE_HIDDEN,
+ SHOW_MODE_WITH_HARD_KEYBOARD
})
public @interface SoftKeyboardShowMode {}
+ /**
+ * Allow the system to control when the soft keyboard is shown.
+ * @see SoftKeyboardController
+ */
public static final int SHOW_MODE_AUTO = 0;
+
+ /**
+ * Never show the soft keyboard.
+ * @see SoftKeyboardController
+ */
public static final int SHOW_MODE_HIDDEN = 1;
+ /**
+ * Allow the soft keyboard to be shown, even if a hard keyboard is connected
+ * @see SoftKeyboardController
+ */
+ public static final int SHOW_MODE_WITH_HARD_KEYBOARD = 2;
+
+ /**
+ * Mask used to cover the show modes supported in public API
+ * @hide
+ */
+ public static final int SHOW_MODE_MASK = 0x03;
+
+ /**
+ * Bit used to hold the old value of the hard IME setting to restore when a service is shut
+ * down.
+ * @hide
+ */
+ public static final int SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE = 0x20000000;
+
+ /**
+ * Bit for show mode setting to indicate that the user has overridden the hard keyboard
+ * behavior.
+ * @hide
+ */
+ public static final int SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN = 0x40000000;
+
private int mConnectionId = AccessibilityInteractionClient.NO_ID;
+ @UnsupportedAppUsage
private AccessibilityServiceInfo mInfo;
+ @UnsupportedAppUsage
private IBinder mWindowToken;
private WindowManager mWindowManager;
@@ -1147,7 +1185,27 @@
}
/**
- * Used to control and query the soft keyboard show mode.
+ * Used to control, query, and listen for changes to the soft keyboard show mode.
+ * <p>
+ * Accessibility services may request to override the decisions normally made about whether or
+ * not the soft keyboard is shown.
+ * <p>
+ * If multiple services make conflicting requests, the last request is honored. A service may
+ * register a listener to find out if the mode has changed under it.
+ * <p>
+ * If the user takes action to override the behavior behavior requested by an accessibility
+ * service, the user's request takes precendence, the show mode will be reset to
+ * {@link AccessibilityService#SHOW_MODE_AUTO}, and services will no longer be able to control
+ * that aspect of the soft keyboard's behavior.
+ * <p>
+ * Note: Because soft keyboards are independent apps, the framework does not have total control
+ * over their behavior. They may choose to show themselves, or not, without regard to requests
+ * made here. So the framework will make a best effort to deliver the behavior requested, but
+ * cannot guarantee success.
+ *
+ * @see AccessibilityService#SHOW_MODE_AUTO
+ * @see AccessibilityService#SHOW_MODE_HIDDEN
+ * @see AccessibilityService#SHOW_MODE_WITH_HARD_KEYBOARD
*/
public static final class SoftKeyboardController {
private final AccessibilityService mService;
@@ -1217,7 +1275,8 @@
* @param listener the listener to remove, must be non-null
* @return {@code true} if the listener was removed, {@code false} otherwise
*/
- public boolean removeOnShowModeChangedListener(@NonNull OnShowModeChangedListener listener) {
+ public boolean removeOnShowModeChangedListener(
+ @NonNull OnShowModeChangedListener listener) {
if (mListeners == null) {
return false;
}
@@ -1289,32 +1348,32 @@
}
/**
- * Returns the show mode of the soft keyboard. The default show mode is
- * {@code SHOW_MODE_AUTO}, where the soft keyboard is shown when a text input field is
- * focused. An AccessibilityService can also request the show mode
- * {@code SHOW_MODE_HIDDEN}, where the soft keyboard is never shown.
+ * Returns the show mode of the soft keyboard.
*
* @return the current soft keyboard show mode
+ *
+ * @see AccessibilityService#SHOW_MODE_AUTO
+ * @see AccessibilityService#SHOW_MODE_HIDDEN
+ * @see AccessibilityService#SHOW_MODE_WITH_HARD_KEYBOARD
*/
@SoftKeyboardShowMode
public int getShowMode() {
- try {
- return Settings.Secure.getInt(mService.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
- } catch (Settings.SettingNotFoundException e) {
- Log.v(LOG_TAG, "Failed to obtain the soft keyboard mode", e);
- // The settings hasn't been changed yet, so it's value is null. Return the default.
- return 0;
- }
+ final IAccessibilityServiceConnection connection =
+ AccessibilityInteractionClient.getInstance().getConnection(
+ mService.mConnectionId);
+ if (connection != null) {
+ try {
+ return connection.getSoftKeyboardShowMode();
+ } catch (RemoteException re) {
+ Log.w(LOG_TAG, "Failed to set soft keyboard behavior", re);
+ re.rethrowFromSystemServer();
+ }
+ }
+ return SHOW_MODE_AUTO;
}
/**
- * Sets the soft keyboard show mode. The default show mode is
- * {@code SHOW_MODE_AUTO}, where the soft keyboard is shown when a text input field is
- * focused. An AccessibilityService can also request the show mode
- * {@code SHOW_MODE_HIDDEN}, where the soft keyboard is never shown. The
- * The lastto this method will be honored, regardless of any previous calls (including those
- * made by other AccessibilityServices).
+ * Sets the soft keyboard show mode.
* <p>
* <strong>Note:</strong> If the service is not yet connected (e.g.
* {@link AccessibilityService#onServiceConnected()} has not yet been called) or the
@@ -1322,6 +1381,10 @@
*
* @param showMode the new show mode for the soft keyboard
* @return {@code true} on success
+ *
+ * @see AccessibilityService#SHOW_MODE_AUTO
+ * @see AccessibilityService#SHOW_MODE_HIDDEN
+ * @see AccessibilityService#SHOW_MODE_WITH_HARD_KEYBOARD
*/
public boolean setShowMode(@SoftKeyboardShowMode int showMode) {
final IAccessibilityServiceConnection connection =
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index ed684d7..be2e2fa 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -19,6 +19,7 @@
import static android.content.pm.PackageManager.FEATURE_FINGERPRINT;
import android.annotation.IntDef;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -695,6 +696,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setCapabilities(int capabilities) {
mCapabilities = capabilities;
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 037aeb0..276131f 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -87,6 +87,8 @@
boolean setSoftKeyboardShowMode(int showMode);
+ int getSoftKeyboardShowMode();
+
void setSoftKeyboardCallbackEnabled(boolean enabled);
boolean isAccessibilityButtonAvailable();
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 4ebcc44..17d54d2 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -17,6 +17,7 @@
package android.animation;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ConstantState;
@@ -460,6 +461,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void reverse() {
throw new IllegalStateException("Reverse is not supported");
}
diff --git a/core/java/android/animation/ArgbEvaluator.java b/core/java/android/animation/ArgbEvaluator.java
index a96bee6..5b69d18 100644
--- a/core/java/android/animation/ArgbEvaluator.java
+++ b/core/java/android/animation/ArgbEvaluator.java
@@ -16,6 +16,8 @@
package android.animation;
+import android.annotation.UnsupportedAppUsage;
+
/**
* This evaluator can be used to perform type interpolation between integer
* values that represent ARGB colors.
@@ -31,6 +33,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static ArgbEvaluator getInstance() {
return sInstance;
}
diff --git a/core/java/android/animation/LayoutTransition.java b/core/java/android/animation/LayoutTransition.java
index 5a23fdd..5b3813d 100644
--- a/core/java/android/animation/LayoutTransition.java
+++ b/core/java/android/animation/LayoutTransition.java
@@ -16,6 +16,7 @@
package android.animation;
+import android.annotation.UnsupportedAppUsage;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -1070,6 +1071,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void cancel() {
if (currentChangingAnimations.size() > 0) {
LinkedHashMap<View, Animator> currentAnimCopy =
@@ -1105,6 +1107,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void cancel(int transitionType) {
switch (transitionType) {
case CHANGE_APPEARING:
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index cc95eb6..a0464df 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -19,6 +19,7 @@
import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.os.Looper;
import android.os.Trace;
import android.util.AndroidRuntimeException;
@@ -75,6 +76,7 @@
/**
* Internal constants
*/
+ @UnsupportedAppUsage
private static float sDurationScale = 1.0f;
/**
@@ -200,6 +202,7 @@
//
// How long the animation should last in ms
+ @UnsupportedAppUsage
private long mDuration = 300;
// The amount of time in ms to delay starting the animation after start() is called. Note
@@ -1534,6 +1537,7 @@
* @param fraction The elapsed fraction of the animation.
*/
@CallSuper
+ @UnsupportedAppUsage
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction);
mCurrentFraction = fraction;
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index c895978..2baae92 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -228,4 +228,7 @@
public abstract boolean isCurrentProfile(int userId);
public abstract boolean hasStartedUserState(int userId);
public abstract void finishUserSwitch(Object uss);
+
+ /** Schedule the execution of all pending app GCs. */
+ public abstract void scheduleAppGcs();
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 151e9a5..2a3fc04 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -259,6 +259,7 @@
final H mH = new H();
final Executor mExecutor = new HandlerExecutor(mH);
final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
+ /** The activities to be truly destroyed (not include relaunch). */
final Map<IBinder, ClientTransactionItem> mActivitiesToBeDestroyed =
Collections.synchronizedMap(new ArrayMap<IBinder, ClientTransactionItem>());
// List of new activities (via ActivityRecord.nextIdle) that should
@@ -3078,6 +3079,10 @@
}
private void reportSizeConfigurations(ActivityClientRecord r) {
+ if (mActivitiesToBeDestroyed.containsKey(r.token)) {
+ // Size configurations of a destroyed activity is meaningless.
+ return;
+ }
Configuration[] configurations = r.activity.getResources().getSizeConfigurations();
if (configurations == null) {
return;
@@ -3826,6 +3831,13 @@
// We didn't actually resume the activity, so skipping any follow-up actions.
return;
}
+ if (mActivitiesToBeDestroyed.containsKey(token)) {
+ // Although the activity is resumed, it is going to be destroyed. So the following
+ // UI operations are unnecessary and also prevents exception because its token may
+ // be gone that window manager cannot recognize it. All necessary cleanup actions
+ // performed below will be done while handling destruction.
+ return;
+ }
final Activity a = r.activity;
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 285f83b..16360b3 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -325,7 +325,6 @@
*/
void requestWifiBugReport(in String shareTitle, in String shareDescription);
- long inputDispatchingTimedOut(int pid, boolean aboveSystem, in String reason);
void clearPendingBackup();
Intent getIntentForIntentSender(in IIntentSender sender);
// This is not public because you need to be very careful in how you
diff --git a/core/java/android/app/IBackupAgent.aidl b/core/java/android/app/IBackupAgent.aidl
index 3aeef14..4517446 100644
--- a/core/java/android/app/IBackupAgent.aidl
+++ b/core/java/android/app/IBackupAgent.aidl
@@ -16,6 +16,7 @@
package android.app;
+import android.app.backup.IBackupCallback;
import android.app.backup.IBackupManager;
import android.os.ParcelFileDescriptor;
@@ -55,7 +56,7 @@
void doBackup(in ParcelFileDescriptor oldState,
in ParcelFileDescriptor data,
in ParcelFileDescriptor newState,
- long quotaBytes, int token, IBackupManager callbackBinder, int transportFlags);
+ long quotaBytes, IBackupCallback callbackBinder, int transportFlags);
/**
* Restore an entire data snapshot to the application.
diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java
index 35a1789..9873a81 100644
--- a/core/java/android/app/WallpaperInfo.java
+++ b/core/java/android/app/WallpaperInfo.java
@@ -315,12 +315,13 @@
}
/**
- * Returns whether a wallpaper was optimized or not for ambient mode.
+ * Returns whether a wallpaper was optimized or not for ambient mode and can be drawn in there.
*
- * @return {@code true} if wallpaper can draw in ambient mode.
- * @hide
+ * @see WallpaperService.Engine#onAmbientModeChanged(boolean, boolean)
+ * @see WallpaperService.Engine#isInAmbientMode()
+ * @return {@code true} if wallpaper can draw when in ambient mode.
*/
- public boolean getSupportsAmbientMode() {
+ public boolean supportsAmbientMode() {
return mSupportsAmbientMode;
}
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 51372c4..15bcbe3 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2237,6 +2237,22 @@
return mWindowNodes.get(index);
}
+ // TODO(b/35708678): temporary method that disable one-way warning flag on binder.
+ /** @hide */
+ public void ensureDataForAutofill() {
+ if (mHaveData) {
+ return;
+ }
+ mHaveData = true;
+ Binder.allowBlocking(mReceiveChannel);
+ try {
+ ParcelTransferReader reader = new ParcelTransferReader(mReceiveChannel);
+ reader.go();
+ } finally {
+ Binder.defaultBlocking(mReceiveChannel);
+ }
+ }
+
/** @hide */
public void ensureData() {
if (mHaveData) {
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index ec2cf0c..097dd9c 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -941,11 +941,13 @@
private static final String TAG = "BackupServiceBinder";
@Override
- public void doBackup(ParcelFileDescriptor oldState,
+ public void doBackup(
+ ParcelFileDescriptor oldState,
ParcelFileDescriptor data,
ParcelFileDescriptor newState,
- long quotaBytes, int token, IBackupManager callbackBinder, int transportFlags)
- throws RemoteException {
+ long quotaBytes,
+ IBackupCallback callbackBinder,
+ int transportFlags) throws RemoteException {
// Ensure that we're running with the app's normal permission level
long ident = Binder.clearCallingIdentity();
@@ -969,7 +971,7 @@
Binder.restoreCallingIdentity(ident);
try {
- callbackBinder.opComplete(token, 0);
+ callbackBinder.operationComplete(0);
} catch (RemoteException e) {
// we'll time out anyway, so we're safe
}
diff --git a/core/java/android/app/backup/IBackupCallback.aidl b/core/java/android/app/backup/IBackupCallback.aidl
new file mode 100644
index 0000000..9582a58
--- /dev/null
+++ b/core/java/android/app/backup/IBackupCallback.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import android.app.backup.IBackupManager;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Callback interface made for responding to one-way calls from the system.
+ *
+ * @hide
+ */
+oneway interface IBackupCallback {
+ void operationComplete(long result);
+}
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index ee752f8..a2a48328 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -48,6 +48,7 @@
public static final int PACKAGE_VERIFIER = 3;
public static final int PACKAGE_BROWSER = 4;
public static final int PACKAGE_SYSTEM_TEXT_CLASSIFIER = 5;
+ public static final int PACKAGE_PERMISSION_CONTROLLER = 6;
@IntDef(value = {
PACKAGE_SYSTEM,
PACKAGE_SETUP_WIZARD,
@@ -55,6 +56,7 @@
PACKAGE_VERIFIER,
PACKAGE_BROWSER,
PACKAGE_SYSTEM_TEXT_CLASSIFIER,
+ PACKAGE_PERMISSION_CONTROLLER,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KnownPackage {}
@@ -671,4 +673,11 @@
* @param delegate A delegate instance or null to clear.
*/
public abstract void setCheckPermissionDelegate(@Nullable CheckPermissionDelegate delegate);
+
+ /**
+ * Get appIds of all available apps which specified android:sharedUserId in the manifest.
+ *
+ * @return a SparseArray mapping from appId to it's sharedUserId.
+ */
+ public abstract SparseArray<String> getAppsWithSharedUserIds();
}
diff --git a/core/java/android/database/DatabaseUtils.java b/core/java/android/database/DatabaseUtils.java
index 3d019f0..7a8ab60 100644
--- a/core/java/android/database/DatabaseUtils.java
+++ b/core/java/android/database/DatabaseUtils.java
@@ -16,6 +16,7 @@
package android.database;
+import android.annotation.Nullable;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
@@ -34,6 +35,8 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.util.ArrayUtils;
+
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.text.Collator;
@@ -216,6 +219,92 @@
}
/**
+ * Bind the given selection with the given selection arguments.
+ * <p>
+ * Internally assumes that '?' is only ever used for arguments, and doesn't
+ * appear as a literal or escaped value.
+ * <p>
+ * This method is typically useful for trusted code that needs to cook up a
+ * fully-bound selection.
+ *
+ * @hide
+ */
+ public static @Nullable String bindSelection(@Nullable String selection,
+ @Nullable Object... selectionArgs) {
+ if (selection == null) return null;
+ // If no arguments provided, so we can't bind anything
+ if (ArrayUtils.isEmpty(selectionArgs)) return selection;
+ // If no bindings requested, so we can shortcut
+ if (selection.indexOf('?') == -1) return selection;
+
+ // Track the chars immediately before and after each bind request, to
+ // decide if it needs additional whitespace added
+ char before = ' ';
+ char after = ' ';
+
+ int argIndex = 0;
+ final int len = selection.length();
+ final StringBuilder res = new StringBuilder(len);
+ for (int i = 0; i < len; ) {
+ char c = selection.charAt(i++);
+ if (c == '?') {
+ // Assume this bind request is guarded until we find a specific
+ // trailing character below
+ after = ' ';
+
+ // Sniff forward to see if the selection is requesting a
+ // specific argument index
+ int start = i;
+ for (; i < len; i++) {
+ c = selection.charAt(i);
+ if (c < '0' || c > '9') {
+ after = c;
+ break;
+ }
+ }
+ if (start != i) {
+ argIndex = Integer.parseInt(selection.substring(start, i)) - 1;
+ }
+
+ // Manually bind the argument into the selection, adding
+ // whitespace when needed for clarity
+ final Object arg = selectionArgs[argIndex++];
+ if (before != ' ' && before != '=') res.append(' ');
+ switch (DatabaseUtils.getTypeOfObject(arg)) {
+ case Cursor.FIELD_TYPE_NULL:
+ res.append("NULL");
+ break;
+ case Cursor.FIELD_TYPE_INTEGER:
+ res.append(((Number) arg).longValue());
+ break;
+ case Cursor.FIELD_TYPE_FLOAT:
+ res.append(((Number) arg).doubleValue());
+ break;
+ case Cursor.FIELD_TYPE_BLOB:
+ throw new IllegalArgumentException("Blobs not supported");
+ case Cursor.FIELD_TYPE_STRING:
+ default:
+ if (arg instanceof Boolean) {
+ // Provide compatibility with legacy applications which may pass
+ // Boolean values in bind args.
+ res.append(((Boolean) arg).booleanValue() ? 1 : 0);
+ } else {
+ res.append('\'');
+ res.append(arg.toString());
+ res.append('\'');
+ }
+ break;
+ }
+ if (after != ' ') res.append(' ');
+ } else {
+ res.append(c);
+ before = c;
+ }
+ }
+ return res.toString();
+ }
+
+ /**
* Returns data type of the given object's value.
*<p>
* Returned values are
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 101fb82..df6447a 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -34,10 +34,10 @@
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Date;
import java.util.Map;
-
/**
* Represents a SQLite database connection.
* Each connection wraps an instance of a native <code>sqlite3</code> object.
@@ -90,6 +90,8 @@
private static final String TAG = "SQLiteConnection";
private static final boolean DEBUG = false;
+ public static volatile boolean sLocalDebug = false;
+
private static final String[] EMPTY_STRING_ARRAY = new String[0];
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
@@ -991,6 +993,10 @@
}
private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
+ if (sLocalDebug) {
+ Log.v(TAG, statement.mSql + " with args " + Arrays.toString(bindArgs));
+ }
+
final int count = bindArgs != null ? bindArgs.length : 0;
if (count != statement.mNumParameters) {
throw new SQLiteBindOrColumnIndexOutOfRangeException(
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 3298140..06560f2 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -43,8 +43,7 @@
* This is a convenience class that helps build SQL queries to be sent to
* {@link SQLiteDatabase} objects.
*/
-public class SQLiteQueryBuilder
-{
+public class SQLiteQueryBuilder {
private static final String TAG = "SQLiteQueryBuilder";
private static final Pattern sLimitPattern =
Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?");
@@ -100,7 +99,7 @@
*
* @param inWhere the chunk of text to append to the WHERE clause.
*/
- public void appendWhere(CharSequence inWhere) {
+ public void appendWhere(@NonNull CharSequence inWhere) {
if (mWhereClause == null) {
mWhereClause = new StringBuilder(inWhere.length() + 16);
}
@@ -117,7 +116,7 @@
* @param inWhere the chunk of text to append to the WHERE clause. it will be escaped
* to avoid SQL injection attacks
*/
- public void appendWhereEscapeString(String inWhere) {
+ public void appendWhereEscapeString(@NonNull String inWhere) {
if (mWhereClause == null) {
mWhereClause = new StringBuilder(inWhere.length() + 16);
}
@@ -125,6 +124,27 @@
}
/**
+ * Add a standalone chunk to the {@code WHERE} clause of this query.
+ * <p>
+ * This method differs from {@link #appendWhere(CharSequence)} in that it
+ * automatically appends {@code AND} to any existing {@code WHERE} clause
+ * already under construction before appending the given standalone
+ * expression wrapped in parentheses.
+ *
+ * @param inWhere the standalone expression to append to the {@code WHERE}
+ * clause. It will be wrapped in parentheses when it's appended.
+ */
+ public void appendWhereStandalone(@NonNull CharSequence inWhere) {
+ if (mWhereClause == null) {
+ mWhereClause = new StringBuilder(inWhere.length() + 16);
+ }
+ if (mWhereClause.length() > 0) {
+ mWhereClause.append(" AND ");
+ }
+ mWhereClause.append('(').append(inWhere).append(')');
+ }
+
+ /**
* Sets the projection map for the query. The projection map maps
* from column names that the caller passes into query to database
* column names. This is useful for renaming columns as well as
diff --git a/core/java/android/database/sqlite/SQLiteStatementBuilder.java b/core/java/android/database/sqlite/SQLiteStatementBuilder.java
deleted file mode 100644
index e2efb2f..0000000
--- a/core/java/android/database/sqlite/SQLiteStatementBuilder.java
+++ /dev/null
@@ -1,1036 +0,0 @@
-/*
- * Copyright (C) 2006 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.database.sqlite;
-
-import static android.content.ContentResolver.QUERY_ARG_SQL_GROUP_BY;
-import static android.content.ContentResolver.QUERY_ARG_SQL_HAVING;
-import static android.content.ContentResolver.QUERY_ARG_SQL_LIMIT;
-import static android.content.ContentResolver.QUERY_ARG_SQL_SELECTION;
-import static android.content.ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS;
-import static android.content.ContentResolver.QUERY_ARG_SQL_SORT_ORDER;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.os.Build;
-import android.os.Bundle;
-import android.os.CancellationSignal;
-import android.os.OperationCanceledException;
-import android.provider.BaseColumns;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import com.android.internal.util.ArrayUtils;
-
-import dalvik.system.VMRuntime;
-
-import libcore.util.EmptyArray;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Set;
-import java.util.regex.Pattern;
-
-/**
- * This is a convenience class that helps build SQL queries to be sent to
- * {@link SQLiteDatabase} objects.
- * @hide
- */
-public class SQLiteStatementBuilder {
- private static final String TAG = "SQLiteStatementBuilder";
- private static final Pattern sLimitPattern =
- Pattern.compile("\\s*\\d+\\s*(,\\s*\\d+\\s*)?");
-
- private Map<String, String> mProjectionMap = null;
- private String mTables = "";
- private StringBuilder mWhereClause = null; // lazily created
- private String[] mWhereArgs = EmptyArray.STRING;
- private boolean mDistinct;
- private SQLiteDatabase.CursorFactory mFactory;
- private boolean mStrict;
-
- public SQLiteStatementBuilder() {
- mDistinct = false;
- mFactory = null;
- }
-
- /**
- * Mark the query as DISTINCT.
- *
- * @param distinct if true the query is DISTINCT, otherwise it isn't
- */
- public void setDistinct(boolean distinct) {
- mDistinct = distinct;
- }
-
- /**
- * Returns the list of tables being queried
- *
- * @return the list of tables being queried
- */
- public String getTables() {
- return mTables;
- }
-
- /**
- * Sets the list of tables to query. Multiple tables can be specified to perform a join.
- * For example:
- * setTables("foo, bar")
- * setTables("foo LEFT OUTER JOIN bar ON (foo.id = bar.foo_id)")
- *
- * @param inTables the list of tables to query on
- */
- public void setTables(String inTables) {
- mTables = inTables;
- }
-
- /** {@hide} */
- public @Nullable String getWhere() {
- return (mWhereClause != null) ? mWhereClause.toString() : null;
- }
-
- /** {@hide} */
- public String[] getWhereArgs() {
- return mWhereArgs;
- }
-
- /**
- * Append a chunk to the {@code WHERE} clause of the query. All chunks
- * appended are surrounded by parenthesis and {@code AND}ed with the
- * selection passed to {@link #query}. The final {@code WHERE} clause looks
- * like:
- *
- * <pre>
- * WHERE (<append chunk 1><append chunk2>) AND (<query() selection parameter>)
- * </pre>
- *
- * @param inWhere the chunk of text to append to the {@code WHERE} clause.
- */
- public void appendWhere(@NonNull CharSequence inWhere) {
- appendWhere(inWhere, EmptyArray.STRING);
- }
-
- /**
- * Append a chunk to the {@code WHERE} clause of the query. All chunks
- * appended are surrounded by parenthesis and {@code AND}ed with the
- * selection passed to {@link #query}. The final {@code WHERE} clause looks
- * like:
- *
- * <pre>
- * WHERE (<append chunk 1><append chunk2>) AND (<query() selection parameter>)
- * </pre>
- *
- * @param inWhere the chunk of text to append to the {@code WHERE} clause.
- * @param inWhereArgs list of arguments to be bound to any '?' occurrences
- * in the where clause.
- */
- public void appendWhere(@NonNull CharSequence inWhere, String... inWhereArgs) {
- if (mWhereClause == null) {
- mWhereClause = new StringBuilder(inWhere.length() + 16);
- }
- mWhereClause.append(inWhere);
- mWhereArgs = ArrayUtils.concat(String.class, mWhereArgs, inWhereArgs);
- }
-
- /**
- * Append a standalone expression to the {@code WHERE} clause of this query.
- * <p>
- * This method differs from {@link #appendWhere(CharSequence)} in that it
- * automatically appends {@code AND} to any existing {@code WHERE} clause
- * already under construction before appending the given standalone
- * expression.
- *
- * @param inWhere the standalone expression to append to the {@code WHERE}
- * clause. It will be wrapped in parentheses when it's appended.
- */
- public void appendWhereExpression(@NonNull CharSequence inWhere) {
- appendWhereExpression(inWhere, EmptyArray.STRING);
- }
-
- /**
- * Append a standalone expression to the {@code WHERE} clause of this query.
- * <p>
- * This method differs from {@link #appendWhere(CharSequence)} in that it
- * automatically appends {@code AND} to any existing {@code WHERE} clause
- * already under construction before appending the given standalone
- * expression.
- *
- * @param inWhere the standalone expression to append to the {@code WHERE}
- * clause. It will be wrapped in parentheses when it's appended.
- * @param inWhereArgs list of arguments to be bound to any '?' occurrences
- * in the standalone expression.
- */
- public void appendWhereExpression(@NonNull CharSequence inWhere, String... inWhereArgs) {
- if (mWhereClause == null) {
- mWhereClause = new StringBuilder(inWhere.length() + 16);
- }
- if (mWhereClause.length() > 0) {
- mWhereClause.append(" AND ");
- }
- mWhereClause.append('(').append(inWhere).append(')');
- mWhereArgs = ArrayUtils.concat(String.class, mWhereArgs, inWhereArgs);
- }
-
- /**
- * Append a chunk to the {@code WHERE} clause of the query. All chunks
- * appended are surrounded by parenthesis and {@code AND}ed with the
- * selection passed to {@link #query}. The final {@code WHERE} clause looks
- * like this:
- *
- * <pre>
- * WHERE (<append chunk 1><append chunk2>) AND (<query() selection parameter>)
- * </pre>
- *
- * @param inWhere the chunk of text to append to the {@code WHERE} clause.
- * It will be escaped to avoid SQL injection attacks.
- */
- public void appendWhereEscapeString(@NonNull String inWhere) {
- appendWhereEscapeString(inWhere, EmptyArray.STRING);
- }
-
- /**
- * Append a chunk to the {@code WHERE} clause of the query. All chunks
- * appended are surrounded by parenthesis and {@code AND}ed with the
- * selection passed to {@link #query}. The final {@code WHERE} clause looks
- * like this:
- *
- * <pre>
- * WHERE (<append chunk 1><append chunk2>) AND (<query() selection parameter>)
- * </pre>
- *
- * @param inWhere the chunk of text to append to the {@code WHERE} clause.
- * It will be escaped to avoid SQL injection attacks.
- * @param inWhereArgs list of arguments to be bound to any '?' occurrences
- * in the where clause.
- */
- public void appendWhereEscapeString(@NonNull String inWhere, String... inWhereArgs) {
- if (mWhereClause == null) {
- mWhereClause = new StringBuilder(inWhere.length() + 16);
- }
- DatabaseUtils.appendEscapedSQLString(mWhereClause, inWhere);
- mWhereArgs = ArrayUtils.concat(String.class, mWhereArgs, inWhereArgs);
- }
-
- /**
- * Sets the projection map for the query. The projection map maps
- * from column names that the caller passes into query to database
- * column names. This is useful for renaming columns as well as
- * disambiguating column names when doing joins. For example you
- * could map "name" to "people.name". If a projection map is set
- * it must contain all column names the user may request, even if
- * the key and value are the same.
- *
- * @param columnMap maps from the user column names to the database column names
- */
- public void setProjectionMap(Map<String, String> columnMap) {
- mProjectionMap = columnMap;
- }
-
- /**
- * Sets the cursor factory to be used for the query. You can use
- * one factory for all queries on a database but it is normally
- * easier to specify the factory when doing this query.
- *
- * @param factory the factory to use.
- */
- public void setCursorFactory(SQLiteDatabase.CursorFactory factory) {
- mFactory = factory;
- }
-
- /**
- * When set, the selection is verified against malicious arguments.
- * When using this class to create a statement using
- * {@link #buildQueryString(boolean, String, String[], String, String, String, String, String)},
- * non-numeric limits will raise an exception. If a projection map is specified, fields
- * not in that map will be ignored.
- * If this class is used to execute the statement directly using
- * {@link #query(SQLiteDatabase, String[], String, String[], String, String, String)}
- * or
- * {@link #query(SQLiteDatabase, String[], String, String[], String, String, String, String)},
- * additionally also parenthesis escaping selection are caught.
- *
- * To summarize: To get maximum protection against malicious third party apps (for example
- * content provider consumers), make sure to do the following:
- * <ul>
- * <li>Set this value to true</li>
- * <li>Use a projection map</li>
- * <li>Use one of the query overloads instead of getting the statement as a sql string</li>
- * </ul>
- * By default, this value is false.
- */
- public void setStrict(boolean strict) {
- mStrict = strict;
- }
-
- /**
- * Build an SQL query string from the given clauses.
- *
- * @param distinct true if you want each row to be unique, false otherwise.
- * @param tables The table names to compile the query against.
- * @param columns A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading
- * data from storage that isn't going to be used.
- * @param where A filter declaring which rows to return, formatted as an SQL
- * WHERE clause (excluding the WHERE itself). Passing null will
- * return all rows for the given URL.
- * @param groupBy A filter declaring how to group rows, formatted as an SQL
- * GROUP BY clause (excluding the GROUP BY itself). Passing null
- * will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in the cursor,
- * if row grouping is being used, formatted as an SQL HAVING
- * clause (excluding the HAVING itself). Passing null will cause
- * all row groups to be included, and is required when row
- * grouping is not being used.
- * @param orderBy How to order the rows, formatted as an SQL ORDER BY clause
- * (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return the SQL query string
- */
- public static String buildQueryString(
- boolean distinct, String tables, String[] columns, String where,
- String groupBy, String having, String orderBy, String limit) {
- if (TextUtils.isEmpty(groupBy) && !TextUtils.isEmpty(having)) {
- throw new IllegalArgumentException(
- "HAVING clauses are only permitted when using a groupBy clause");
- }
- if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) {
- throw new IllegalArgumentException("invalid LIMIT clauses:" + limit);
- }
-
- StringBuilder query = new StringBuilder(120);
-
- query.append("SELECT ");
- if (distinct) {
- query.append("DISTINCT ");
- }
- if (columns != null && columns.length != 0) {
- appendColumns(query, columns);
- } else {
- query.append("* ");
- }
- query.append("FROM ");
- query.append(tables);
- appendClause(query, " WHERE ", where);
- appendClause(query, " GROUP BY ", groupBy);
- appendClause(query, " HAVING ", having);
- appendClause(query, " ORDER BY ", orderBy);
- appendClause(query, " LIMIT ", limit);
-
- return query.toString();
- }
-
- private static void appendClause(StringBuilder s, String name, String clause) {
- if (!TextUtils.isEmpty(clause)) {
- s.append(name);
- s.append(clause);
- }
- }
-
- /**
- * Add the names that are non-null in columns to s, separating
- * them with commas.
- */
- public static void appendColumns(StringBuilder s, String[] columns) {
- int n = columns.length;
-
- for (int i = 0; i < n; i++) {
- String column = columns[i];
-
- if (column != null) {
- if (i > 0) {
- s.append(", ");
- }
- s.append(column);
- }
- }
- s.append(' ');
- }
-
- /**
- * Perform a query by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to query on
- * @param projection A list of which columns to return. Passing
- * null will return all columns, which is discouraged to prevent
- * reading data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY
- * itself). Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @return a cursor over the result set
- * @see android.content.ContentResolver#query(android.net.Uri, String[],
- * String, String[], String)
- */
- public @Nullable Cursor query(@NonNull SQLiteDatabase db,
- @Nullable String[] projection,
- @Nullable String selection,
- @Nullable String[] selectionArgs,
- @Nullable String groupBy,
- @Nullable String having,
- @Nullable String sortOrder) {
- return query(db, projection, selection, selectionArgs, groupBy, having, sortOrder,
- null /* limit */, null /* cancellationSignal */);
- }
-
- /**
- * Perform a query by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to query on
- * @param projection A list of which columns to return. Passing
- * null will return all columns, which is discouraged to prevent
- * reading data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY
- * itself). Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return a cursor over the result set
- * @see android.content.ContentResolver#query(android.net.Uri, String[],
- * String, String[], String)
- */
- public @Nullable Cursor query(@NonNull SQLiteDatabase db,
- @Nullable String[] projection,
- @Nullable String selection,
- @Nullable String[] selectionArgs,
- @Nullable String groupBy,
- @Nullable String having,
- @Nullable String sortOrder,
- @Nullable String limit) {
- return query(db, projection, selection, selectionArgs,
- groupBy, having, sortOrder, limit, null);
- }
-
- /**
- * Perform a query by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to query on
- * @param projection A list of which columns to return. Passing
- * null will return all columns, which is discouraged to prevent
- * reading data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
- * If the operation is canceled, then {@link OperationCanceledException} will be thrown
- * when the query is executed.
- * @return a cursor over the result set
- * @see android.content.ContentResolver#query(android.net.Uri, String[],
- * String, String[], String)
- */
- public @Nullable Cursor query(@NonNull SQLiteDatabase db,
- @Nullable String[] projection,
- @Nullable String selection,
- @Nullable String[] selectionArgs,
- @Nullable String sortOrder,
- @Nullable CancellationSignal cancellationSignal) {
- return query(db, projection, selection, selectionArgs, null, null, sortOrder, null,
- cancellationSignal);
- }
-
- /**
- * Perform a query by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to query on
- * @param projection A list of which columns to return. Passing
- * null will return all columns, which is discouraged to prevent
- * reading data from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY
- * itself). Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @param cancellationSignal A signal to cancel the operation in progress, or null if none.
- * If the operation is canceled, then {@link OperationCanceledException} will be thrown
- * when the query is executed.
- * @return a cursor over the result set
- * @see android.content.ContentResolver#query(android.net.Uri, String[],
- * String, String[], String)
- */
- public @Nullable Cursor query(@NonNull SQLiteDatabase db,
- @Nullable String[] projection,
- @Nullable String selection,
- @Nullable String[] selectionArgs,
- @Nullable String groupBy,
- @Nullable String having,
- @Nullable String sortOrder,
- @Nullable String limit,
- @Nullable CancellationSignal cancellationSignal) {
- final Bundle queryArgs = new Bundle();
- maybePutString(queryArgs, QUERY_ARG_SQL_SELECTION, selection);
- maybePutStringArray(queryArgs, QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs);
- maybePutString(queryArgs, QUERY_ARG_SQL_GROUP_BY, groupBy);
- maybePutString(queryArgs, QUERY_ARG_SQL_HAVING, having);
- maybePutString(queryArgs, QUERY_ARG_SQL_SORT_ORDER, sortOrder);
- maybePutString(queryArgs, QUERY_ARG_SQL_LIMIT, limit);
- return query(db, projection, queryArgs, cancellationSignal);
- }
-
- /**
- * Perform a query by combining all current settings and the information
- * passed into this method.
- *
- * @param db the database to query on
- * @param projection A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading
- * data from storage that isn't going to be used.
- * @param queryArgs A collection of arguments for the query, defined using
- * keys such as {@link ContentResolver#QUERY_ARG_SQL_SELECTION}
- * and {@link ContentResolver#QUERY_ARG_SQL_SELECTION_ARGS}.
- * @param cancellationSignal A signal to cancel the operation in progress,
- * or null if none. If the operation is canceled, then
- * {@link OperationCanceledException} will be thrown when the
- * query is executed.
- * @return a cursor over the result set
- */
- public Cursor query(@NonNull SQLiteDatabase db,
- @Nullable String[] projection,
- @Nullable Bundle queryArgs,
- @Nullable CancellationSignal cancellationSignal) {
- Objects.requireNonNull(db, "No database defined");
-
- if (VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.Q) {
- Objects.requireNonNull(mTables, "No tables defined");
- } else if (mTables == null) {
- return null;
- }
-
- if (queryArgs == null) {
- queryArgs = Bundle.EMPTY;
- }
-
- // Final SQL that we will execute
- final String sql;
-
- final String unwrappedSql = buildQuery(projection,
- queryArgs.getString(QUERY_ARG_SQL_SELECTION),
- queryArgs.getString(QUERY_ARG_SQL_GROUP_BY),
- queryArgs.getString(QUERY_ARG_SQL_HAVING),
- queryArgs.getString(QUERY_ARG_SQL_SORT_ORDER),
- queryArgs.getString(QUERY_ARG_SQL_LIMIT));
-
- if (mStrict) {
- // Validate the user-supplied selection to detect syntactic anomalies
- // in the selection string that could indicate a SQL injection attempt.
- // The idea is to ensure that the selection clause is a valid SQL expression
- // by compiling it twice: once wrapped in parentheses and once as
- // originally specified. An attacker cannot create an expression that
- // would escape the SQL expression while maintaining balanced parentheses
- // in both the wrapped and original forms.
-
- // NOTE: The ordering of the below operations is important; we must
- // execute the wrapped query to ensure the untrusted clause has been
- // fully isolated.
-
- // TODO: decode SORT ORDER and LIMIT clauses, since they can contain
- // "expr" inside that need to be validated
-
- final String wrappedSql = buildQuery(projection,
- wrap(queryArgs.getString(QUERY_ARG_SQL_SELECTION)),
- queryArgs.getString(QUERY_ARG_SQL_GROUP_BY),
- queryArgs.getString(QUERY_ARG_SQL_HAVING),
- queryArgs.getString(QUERY_ARG_SQL_SORT_ORDER),
- queryArgs.getString(QUERY_ARG_SQL_LIMIT));
-
- // Validate the unwrapped query
- db.validateSql(unwrappedSql, cancellationSignal);
-
- // Execute wrapped query for extra protection
- sql = wrappedSql;
- } else {
- // Execute unwrapped query
- sql = unwrappedSql;
- }
-
- final String[] sqlArgs = ArrayUtils.concat(String.class,
- queryArgs.getStringArray(QUERY_ARG_SQL_SELECTION_ARGS), mWhereArgs);
-
- if (Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
- }
-
- return db.rawQueryWithFactory(
- mFactory, sql, sqlArgs,
- SQLiteDatabase.findEditTable(mTables),
- cancellationSignal); // will throw if query is invalid
- }
-
- /**
- * Perform an update by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to update on
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @return the number of rows updated
- */
- public int update(@NonNull SQLiteDatabase db, @NonNull ContentValues values,
- @Nullable String selection, @Nullable String[] selectionArgs) {
- Objects.requireNonNull(mTables, "No tables defined");
- Objects.requireNonNull(db, "No database defined");
- Objects.requireNonNull(values, "No values defined");
-
- if (mStrict) {
- // Validate the user-supplied selection to detect syntactic anomalies
- // in the selection string that could indicate a SQL injection attempt.
- // The idea is to ensure that the selection clause is a valid SQL expression
- // by compiling it twice: once wrapped in parentheses and once as
- // originally specified. An attacker cannot create an expression that
- // would escape the SQL expression while maintaining balanced parentheses
- // in both the wrapped and original forms.
- final String sql = buildUpdate(values, wrap(selection));
- db.validateSql(sql, null); // will throw if query is invalid
- }
-
- final ArrayMap<String, Object> rawValues = values.getValues();
- final String[] updateArgs = new String[rawValues.size()];
- for (int i = 0; i < updateArgs.length; i++) {
- final Object arg = rawValues.valueAt(i);
- updateArgs[i] = (arg != null) ? arg.toString() : null;
- }
-
- final String sql = buildUpdate(values, selection);
- final String[] sqlArgs = ArrayUtils.concat(String.class, updateArgs,
- ArrayUtils.concat(String.class, selectionArgs, mWhereArgs));
-
- if (Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
- }
-
- return db.executeSql(sql, sqlArgs);
- }
-
- /**
- * Perform a delete by combining all current settings and the
- * information passed into this method.
- *
- * @param db the database to delete on
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given URL.
- * @param selectionArgs You may include ?s in selection, which
- * will be replaced by the values from selectionArgs, in order
- * that they appear in the selection. The values will be bound
- * as Strings.
- * @return the number of rows deleted
- */
- public int delete(@NonNull SQLiteDatabase db, @Nullable String selection,
- @Nullable String[] selectionArgs) {
- Objects.requireNonNull(mTables, "No tables defined");
- Objects.requireNonNull(db, "No database defined");
-
- if (mStrict) {
- // Validate the user-supplied selection to detect syntactic anomalies
- // in the selection string that could indicate a SQL injection attempt.
- // The idea is to ensure that the selection clause is a valid SQL expression
- // by compiling it twice: once wrapped in parentheses and once as
- // originally specified. An attacker cannot create an expression that
- // would escape the SQL expression while maintaining balanced parentheses
- // in both the wrapped and original forms.
- final String sql = buildDelete(wrap(selection));
- db.validateSql(sql, null); // will throw if query is invalid
- }
-
- final String sql = buildDelete(selection);
- final String[] sqlArgs = ArrayUtils.concat(String.class, selectionArgs, mWhereArgs);
-
- if (Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, sql + " with args " + Arrays.toString(sqlArgs));
- }
-
- return db.executeSql(sql, sqlArgs);
- }
-
- /**
- * Construct a SELECT statement suitable for use in a group of
- * SELECT statements that will be joined through UNION operators
- * in buildUnionQuery.
- *
- * @param projectionIn A list of which columns to return. Passing
- * null will return all columns, which is discouraged to
- * prevent reading data from storage that isn't going to be
- * used.
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given
- * URL.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY itself).
- * Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing null
- * will use the default sort order, which may be unordered.
- * @param limit Limits the number of rows returned by the query,
- * formatted as LIMIT clause. Passing null denotes no LIMIT clause.
- * @return the resulting SQL SELECT statement
- */
- public String buildQuery(
- String[] projectionIn, String selection, String groupBy,
- String having, String sortOrder, String limit) {
- String[] projection = computeProjection(projectionIn);
- String where = computeWhere(selection);
-
- return buildQueryString(
- mDistinct, mTables, projection, where,
- groupBy, having, sortOrder, limit);
- }
-
- /**
- * @deprecated This method's signature is misleading since no SQL parameter
- * substitution is carried out. The selection arguments parameter does not get
- * used at all. To avoid confusion, call
- * {@link #buildQuery(String[], String, String, String, String, String)} instead.
- */
- @Deprecated
- public String buildQuery(
- String[] projectionIn, String selection, String[] selectionArgs,
- String groupBy, String having, String sortOrder, String limit) {
- return buildQuery(projectionIn, selection, groupBy, having, sortOrder, limit);
- }
-
- /** {@hide} */
- public String buildUpdate(ContentValues values, String selection) {
- if (values == null || values.isEmpty()) {
- throw new IllegalArgumentException("Empty values");
- }
-
- StringBuilder sql = new StringBuilder(120);
- sql.append("UPDATE ");
- sql.append(mTables);
- sql.append(" SET ");
-
- final ArrayMap<String, Object> rawValues = values.getValues();
- for (int i = 0; i < rawValues.size(); i++) {
- if (i > 0) {
- sql.append(',');
- }
- sql.append(rawValues.keyAt(i));
- sql.append("=?");
- }
-
- final String where = computeWhere(selection);
- appendClause(sql, " WHERE ", where);
- return sql.toString();
- }
-
- /** {@hide} */
- public String buildDelete(String selection) {
- StringBuilder sql = new StringBuilder(120);
- sql.append("DELETE FROM ");
- sql.append(mTables);
-
- final String where = computeWhere(selection);
- appendClause(sql, " WHERE ", where);
- return sql.toString();
- }
-
- /**
- * Construct a SELECT statement suitable for use in a group of
- * SELECT statements that will be joined through UNION operators
- * in buildUnionQuery.
- *
- * @param typeDiscriminatorColumn the name of the result column
- * whose cells will contain the name of the table from which
- * each row was drawn.
- * @param unionColumns the names of the columns to appear in the
- * result. This may include columns that do not appear in the
- * table this SELECT is querying (i.e. mTables), but that do
- * appear in one of the other tables in the UNION query that we
- * are constructing.
- * @param columnsPresentInTable a Set of the names of the columns
- * that appear in this table (i.e. in the table whose name is
- * mTables). Since columns in unionColumns include columns that
- * appear only in other tables, we use this array to distinguish
- * which ones actually are present. Other columns will have
- * NULL values for results from this subquery.
- * @param computedColumnsOffset all columns in unionColumns before
- * this index are included under the assumption that they're
- * computed and therefore won't appear in columnsPresentInTable,
- * e.g. "date * 1000 as normalized_date"
- * @param typeDiscriminatorValue the value used for the
- * type-discriminator column in this subquery
- * @param selection A filter declaring which rows to return,
- * formatted as an SQL WHERE clause (excluding the WHERE
- * itself). Passing null will return all rows for the given
- * URL.
- * @param groupBy A filter declaring how to group rows, formatted
- * as an SQL GROUP BY clause (excluding the GROUP BY itself).
- * Passing null will cause the rows to not be grouped.
- * @param having A filter declare which row groups to include in
- * the cursor, if row grouping is being used, formatted as an
- * SQL HAVING clause (excluding the HAVING itself). Passing
- * null will cause all row groups to be included, and is
- * required when row grouping is not being used.
- * @return the resulting SQL SELECT statement
- */
- public String buildUnionSubQuery(
- String typeDiscriminatorColumn,
- String[] unionColumns,
- Set<String> columnsPresentInTable,
- int computedColumnsOffset,
- String typeDiscriminatorValue,
- String selection,
- String groupBy,
- String having) {
- int unionColumnsCount = unionColumns.length;
- String[] projectionIn = new String[unionColumnsCount];
-
- for (int i = 0; i < unionColumnsCount; i++) {
- String unionColumn = unionColumns[i];
-
- if (unionColumn.equals(typeDiscriminatorColumn)) {
- projectionIn[i] = "'" + typeDiscriminatorValue + "' AS "
- + typeDiscriminatorColumn;
- } else if (i <= computedColumnsOffset
- || columnsPresentInTable.contains(unionColumn)) {
- projectionIn[i] = unionColumn;
- } else {
- projectionIn[i] = "NULL AS " + unionColumn;
- }
- }
- return buildQuery(
- projectionIn, selection, groupBy, having,
- null /* sortOrder */,
- null /* limit */);
- }
-
- /**
- * @deprecated This method's signature is misleading since no SQL parameter
- * substitution is carried out. The selection arguments parameter does not get
- * used at all. To avoid confusion, call
- * {@link #buildUnionSubQuery}
- * instead.
- */
- @Deprecated
- public String buildUnionSubQuery(
- String typeDiscriminatorColumn,
- String[] unionColumns,
- Set<String> columnsPresentInTable,
- int computedColumnsOffset,
- String typeDiscriminatorValue,
- String selection,
- String[] selectionArgs,
- String groupBy,
- String having) {
- return buildUnionSubQuery(
- typeDiscriminatorColumn, unionColumns, columnsPresentInTable,
- computedColumnsOffset, typeDiscriminatorValue, selection,
- groupBy, having);
- }
-
- /**
- * Given a set of subqueries, all of which are SELECT statements,
- * construct a query that returns the union of what those
- * subqueries return.
- * @param subQueries an array of SQL SELECT statements, all of
- * which must have the same columns as the same positions in
- * their results
- * @param sortOrder How to order the rows, formatted as an SQL
- * ORDER BY clause (excluding the ORDER BY itself). Passing
- * null will use the default sort order, which may be unordered.
- * @param limit The limit clause, which applies to the entire union result set
- *
- * @return the resulting SQL SELECT statement
- */
- public String buildUnionQuery(String[] subQueries, String sortOrder, String limit) {
- StringBuilder query = new StringBuilder(128);
- int subQueryCount = subQueries.length;
- String unionOperator = mDistinct ? " UNION " : " UNION ALL ";
-
- for (int i = 0; i < subQueryCount; i++) {
- if (i > 0) {
- query.append(unionOperator);
- }
- query.append(subQueries[i]);
- }
- appendClause(query, " ORDER BY ", sortOrder);
- appendClause(query, " LIMIT ", limit);
- return query.toString();
- }
-
- private @Nullable String[] computeProjection(@Nullable String[] projectionIn) {
- if (projectionIn != null && projectionIn.length > 0) {
- if (mProjectionMap != null) {
- String[] projection = new String[projectionIn.length];
- int length = projectionIn.length;
-
- for (int i = 0; i < length; i++) {
- String userColumn = projectionIn[i];
- String column = mProjectionMap.get(userColumn);
-
- if (column != null) {
- projection[i] = column;
- continue;
- }
-
- if (!mStrict &&
- ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
- /* A column alias already exist */
- projection[i] = userColumn;
- continue;
- }
-
- throw new IllegalArgumentException("Invalid column "
- + projectionIn[i] + " from tables " + mTables);
- }
- return projection;
- } else {
- return projectionIn;
- }
- } else if (mProjectionMap != null) {
- // Return all columns in projection map.
- Set<Entry<String, String>> entrySet = mProjectionMap.entrySet();
- String[] projection = new String[entrySet.size()];
- Iterator<Entry<String, String>> entryIter = entrySet.iterator();
- int i = 0;
-
- while (entryIter.hasNext()) {
- Entry<String, String> entry = entryIter.next();
-
- // Don't include the _count column when people ask for no projection.
- if (entry.getKey().equals(BaseColumns._COUNT)) {
- continue;
- }
- projection[i++] = entry.getValue();
- }
- return projection;
- }
- return null;
- }
-
- private @NonNull String computeWhere(@Nullable String selection) {
- final boolean hasUser = selection != null && selection.length() > 0;
- final boolean hasInternal = mWhereClause != null && mWhereClause.length() > 0;
-
- if (hasUser || hasInternal) {
- final StringBuilder where = new StringBuilder();
- if (hasUser) {
- where.append('(').append(selection).append(')');
- }
- if (hasUser && hasInternal) {
- where.append(" AND ");
- }
- if (hasInternal) {
- where.append('(').append(mWhereClause.toString()).append(')');
- }
- return where.toString();
- } else {
- return null;
- }
- }
-
- /**
- * Wrap given argument in parenthesis, unless it's {@code null} or
- * {@code ()}, in which case return it verbatim.
- */
- private @Nullable String wrap(@Nullable String arg) {
- if (arg == null) {
- return null;
- } else if (arg.equals("")) {
- return arg;
- } else {
- return "(" + arg + ")";
- }
- }
-
- private static void maybePutString(@NonNull Bundle bundle, @NonNull String key,
- @Nullable String value) {
- if (value != null) {
- bundle.putString(key, value);
- }
- }
-
- private static void maybePutStringArray(@NonNull Bundle bundle, @NonNull String key,
- @Nullable String[] value) {
- if (value != null) {
- bundle.putStringArray(key, value);
- }
- }
-}
diff --git a/core/java/android/ddm/DdmHandleAppName.java b/core/java/android/ddm/DdmHandleAppName.java
index 7e39e47..9560787 100644
--- a/core/java/android/ddm/DdmHandleAppName.java
+++ b/core/java/android/ddm/DdmHandleAppName.java
@@ -16,6 +16,7 @@
package android.ddm;
+import android.annotation.UnsupportedAppUsage;
import org.apache.harmony.dalvik.ddmc.Chunk;
import org.apache.harmony.dalvik.ddmc.ChunkHandler;
import org.apache.harmony.dalvik.ddmc.DdmServer;
@@ -69,6 +70,7 @@
* before or after DDMS connects. For the latter we need to send up
* an APNM message.
*/
+ @UnsupportedAppUsage
public static void setAppName(String name, int userId) {
if (name == null || name.length() == 0)
return;
@@ -79,6 +81,7 @@
sendAPNM(name, userId);
}
+ @UnsupportedAppUsage
public static String getAppName() {
return mAppName;
}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 431c651..46671b2 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -28,6 +28,7 @@
import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.Context;
@@ -343,10 +344,12 @@
InputMethodManager mImm;
+ @UnsupportedAppUsage
int mTheme = 0;
LayoutInflater mInflater;
TypedArray mThemeAttrs;
+ @UnsupportedAppUsage
View mRootView;
SoftInputWindow mWindow;
boolean mInitialized;
@@ -378,8 +381,10 @@
boolean mFullscreenApplied;
boolean mIsFullscreen;
+ @UnsupportedAppUsage
View mExtractView;
boolean mExtractViewHidden;
+ @UnsupportedAppUsage
ExtractEditText mExtractEditText;
ViewGroup mExtractAccessories;
View mExtractAction;
@@ -402,6 +407,7 @@
*/
boolean mShouldClearInsetOfPreviousIme;
+ @UnsupportedAppUsage
final Insets mTmpInsets = new Insets();
final int[] mTmpLocation = new int[2];
@@ -811,6 +817,7 @@
mService.getContentResolver().unregisterContentObserver(this);
}
+ @UnsupportedAppUsage
private boolean shouldShowImeWithHardKeyboard() {
// Lazily initialize as needed.
if (mShowImeWithHardKeyboard == ShowImeWithHardKeyboardType.UNKNOWN) {
@@ -850,6 +857,7 @@
return "SettingsObserver{mShowImeWithHardKeyboard=" + mShowImeWithHardKeyboard + "}";
}
}
+ @UnsupportedAppUsage
private SettingsObserver mSettingsObserver;
/**
@@ -2492,6 +2500,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void onExtractedDeleteText(int start, int end) {
InputConnection conn = getCurrentInputConnection();
if (conn != null) {
@@ -2504,6 +2513,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void onExtractedReplaceText(int start, int end, CharSequence text) {
InputConnection conn = getCurrentInputConnection();
if (conn != null) {
@@ -2515,6 +2525,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void onExtractedSetSpan(Object span, int start, int end, int flags) {
InputConnection conn = getCurrentInputConnection();
if (conn != null) {
diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java
index a5490ef..ec5f050 100644
--- a/core/java/android/inputmethodservice/Keyboard.java
+++ b/core/java/android/inputmethodservice/Keyboard.java
@@ -18,6 +18,7 @@
import org.xmlpull.v1.XmlPullParserException;
+import android.annotation.UnsupportedAppUsage;
import android.annotation.XmlRes;
import android.content.Context;
import android.content.res.Resources;
@@ -110,18 +111,21 @@
private int mKeyHeight;
/** Total height of the keyboard, including the padding and keys */
+ @UnsupportedAppUsage
private int mTotalHeight;
/**
* Total width of the keyboard, including left side gaps and keys, but not any gaps on the
* right side.
*/
+ @UnsupportedAppUsage
private int mTotalWidth;
/** List of keys in this keyboard */
private List<Key> mKeys;
/** List of modifier keys such as Shift & Alt, if any */
+ @UnsupportedAppUsage
private List<Key> mModifierKeys;
/** Width of the screen available to fit the keyboard */
@@ -623,6 +627,7 @@
rows.add(row);
}
+ @UnsupportedAppUsage
final void resize(int newWidth, int newHeight) {
int numRows = rows.size();
for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) {
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 16c1f6d..9ca8049 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -16,6 +16,7 @@
package android.inputmethodservice;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
@@ -133,6 +134,7 @@
private Keyboard mKeyboard;
private int mCurrentKeyIndex = NOT_A_KEY;
+ @UnsupportedAppUsage
private int mLabelTextSize;
private int mKeyTextSize;
private int mKeyTextColor;
@@ -140,6 +142,7 @@
private int mShadowColor;
private float mBackgroundDimAmount;
+ @UnsupportedAppUsage
private TextView mPreviewText;
private PopupWindow mPreviewPopup;
private int mPreviewTextSizeLarge;
@@ -217,6 +220,7 @@
private float mOldPointerX;
private float mOldPointerY;
+ @UnsupportedAppUsage
private Drawable mKeyBackground;
private static final int REPEAT_INTERVAL = 50; // ~20 keys per second
@@ -910,6 +914,7 @@
}
}
+ @UnsupportedAppUsage
private void showKey(final int keyIndex) {
final PopupWindow previewPopup = mPreviewPopup;
final Key[] keys = mKeys;
@@ -1052,6 +1057,7 @@
key.x + key.width + mPaddingLeft, key.y + key.height + mPaddingTop);
}
+ @UnsupportedAppUsage
private boolean openPopupIfRequired(MotionEvent me) {
// Check if we have a popup layout specified first.
if (mPopupLayout == 0) {
@@ -1357,6 +1363,7 @@
return true;
}
+ @UnsupportedAppUsage
private boolean repeatKey() {
Key key = mKeys[mRepeatKeyIndex];
detectAndSendKey(mCurrentKey, key.x, key.y, mLastTapTime);
diff --git a/core/java/android/nfc/ErrorCodes.java b/core/java/android/nfc/ErrorCodes.java
index 3adcdc3..98e31ad 100644
--- a/core/java/android/nfc/ErrorCodes.java
+++ b/core/java/android/nfc/ErrorCodes.java
@@ -16,6 +16,8 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
+
/**
* This class defines all the error codes that can be returned by the service
* and producing an exception on the application level. These are needed since
@@ -25,6 +27,7 @@
*/
public class ErrorCodes {
+ @UnsupportedAppUsage
public static boolean isError(int code) {
if (code < 0) {
return true;
diff --git a/core/java/android/nfc/NdefRecord.java b/core/java/android/nfc/NdefRecord.java
index 093a9b4..b0090ca 100644
--- a/core/java/android/nfc/NdefRecord.java
+++ b/core/java/android/nfc/NdefRecord.java
@@ -16,6 +16,7 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
@@ -279,6 +280,7 @@
private final short mTnf;
private final byte[] mType;
+ @UnsupportedAppUsage
private final byte[] mId;
private final byte[] mPayload;
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 958063a..abfa133 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -16,6 +16,7 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.Application;
import android.content.ContentProvider;
@@ -45,6 +46,7 @@
static final String TAG = NfcAdapter.TAG;
static final Boolean DBG = false;
+ @UnsupportedAppUsage
final NfcAdapter mAdapter;
// All objects in the lists are protected by this
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index c3f23a1..21fed48 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -20,6 +20,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.ActivityThread;
import android.app.OnActivityPausedListener;
@@ -325,6 +326,7 @@
// Final after first constructor, except for
// attemptDeadServiceRecovery() when NFC crashes - we accept a best effort
// recovery
+ @UnsupportedAppUsage
static INfcAdapter sService;
static INfcTag sTagService;
static INfcCardEmulation sCardEmulationService;
@@ -490,6 +492,7 @@
* or throws if NFC is not available.
* @hide
*/
+ @UnsupportedAppUsage
public static synchronized NfcAdapter getNfcAdapter(Context context) {
if (!sIsInitialized) {
sHasNfcFeature = hasNfcFeature();
@@ -593,6 +596,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
public static NfcAdapter getDefaultAdapter() {
// introduced in API version 9 (GB 2.3)
// deprecated in API version 10 (GB 2.3.3)
@@ -615,6 +619,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public Context getContext() {
return mContext;
}
@@ -623,6 +628,7 @@
* Returns the binder interface to the service.
* @hide
*/
+ @UnsupportedAppUsage
public INfcAdapter getService() {
isEnabled(); // NOP call to recover sService if it is stale
return sService;
@@ -676,6 +682,7 @@
* NFC service dead - attempt best effort recovery
* @hide
*/
+ @UnsupportedAppUsage
public void attemptDeadServiceRecovery(Exception e) {
Log.e(TAG, "NFC service dead - attempting to recover", e);
INfcAdapter service = getServiceInterface();
@@ -746,6 +753,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public int getAdapterState() {
try {
return sService.getState();
@@ -1227,6 +1235,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
int flags) {
if (activity == null) {
@@ -1862,6 +1871,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public INfcAdapterExtras getNfcAdapterExtrasInterface() {
if (mContext == null) {
throw new UnsupportedOperationException("You need a context on NfcAdapter to use the "
diff --git a/core/java/android/nfc/NfcManager.java b/core/java/android/nfc/NfcManager.java
index 50d6745..71199c9 100644
--- a/core/java/android/nfc/NfcManager.java
+++ b/core/java/android/nfc/NfcManager.java
@@ -17,6 +17,7 @@
package android.nfc;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
/**
@@ -44,6 +45,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public NfcManager(Context context) {
NfcAdapter adapter;
context = context.getApplicationContext();
diff --git a/core/java/android/nfc/Tag.java b/core/java/android/nfc/Tag.java
index 154d5a1..ce684cf 100644
--- a/core/java/android/nfc/Tag.java
+++ b/core/java/android/nfc/Tag.java
@@ -16,6 +16,7 @@
package android.nfc;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
@@ -110,6 +111,7 @@
* <p>
*/
public final class Tag implements Parcelable {
+ @UnsupportedAppUsage
final byte[] mId;
final int[] mTechList;
final String[] mTechStringList;
@@ -235,6 +237,7 @@
* For use by NfcService only.
* @hide
*/
+ @UnsupportedAppUsage
public int getServiceHandle() {
return mServiceHandle;
}
@@ -355,6 +358,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public INfcTag getTagService() {
return mTagService;
}
diff --git a/core/java/android/nfc/cardemulation/AidGroup.java b/core/java/android/nfc/cardemulation/AidGroup.java
index 78a9401..63776c4 100644
--- a/core/java/android/nfc/cardemulation/AidGroup.java
+++ b/core/java/android/nfc/cardemulation/AidGroup.java
@@ -24,6 +24,7 @@
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -45,8 +46,11 @@
static final String TAG = "AidGroup";
+ @UnsupportedAppUsage
final List<String> aids;
+ @UnsupportedAppUsage
final String category;
+ @UnsupportedAppUsage
final String description;
/**
@@ -79,6 +83,7 @@
this.description = null;
}
+ @UnsupportedAppUsage
AidGroup(String category, String description) {
this.aids = new ArrayList<String>();
this.category = category;
@@ -88,6 +93,7 @@
/**
* @return the category of this AID group
*/
+ @UnsupportedAppUsage
public String getCategory() {
return category;
}
@@ -95,6 +101,7 @@
/**
* @return the list of AIDs in this group
*/
+ @UnsupportedAppUsage
public List<String> getAids() {
return aids;
}
@@ -124,6 +131,7 @@
}
}
+ @UnsupportedAppUsage
public static final Parcelable.Creator<AidGroup> CREATOR =
new Parcelable.Creator<AidGroup>() {
@@ -144,6 +152,7 @@
}
};
+ @UnsupportedAppUsage
static public AidGroup createFromXml(XmlPullParser parser) throws XmlPullParserException, IOException {
String category = null;
ArrayList<String> aids = new ArrayList<String>();
@@ -185,6 +194,7 @@
return group;
}
+ @UnsupportedAppUsage
public void writeAsXml(XmlSerializer out) throws IOException {
out.startTag(null, "aid-group");
out.attribute(null, "category", category);
diff --git a/core/java/android/nfc/cardemulation/ApduServiceInfo.java b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
index 218e4f2..e8d801c 100644
--- a/core/java/android/nfc/cardemulation/ApduServiceInfo.java
+++ b/core/java/android/nfc/cardemulation/ApduServiceInfo.java
@@ -16,6 +16,7 @@
package android.nfc.cardemulation;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -54,6 +55,7 @@
/**
* The service that implements this
*/
+ @UnsupportedAppUsage
final ResolveInfo mService;
/**
@@ -69,11 +71,13 @@
/**
* Mapping from category to static AID group
*/
+ @UnsupportedAppUsage
final HashMap<String, AidGroup> mStaticAidGroups;
/**
* Mapping from category to dynamic AID group
*/
+ @UnsupportedAppUsage
final HashMap<String, AidGroup> mDynamicAidGroups;
/**
@@ -99,6 +103,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public ApduServiceInfo(ResolveInfo info, boolean onHost, String description,
ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups,
boolean requiresUnlock, int bannerResource, int uid,
@@ -120,6 +125,7 @@
this.mSettingsActivityName = settingsActivityName;
}
+ @UnsupportedAppUsage
public ApduServiceInfo(PackageManager pm, ResolveInfo info, boolean onHost) throws
XmlPullParserException, IOException {
ServiceInfo si = info.serviceInfo;
@@ -374,18 +380,22 @@
return (mStaticAidGroups.containsKey(category) || mDynamicAidGroups.containsKey(category));
}
+ @UnsupportedAppUsage
public boolean isOnHost() {
return mOnHost;
}
+ @UnsupportedAppUsage
public boolean requiresUnlock() {
return mRequiresDeviceUnlock;
}
+ @UnsupportedAppUsage
public String getDescription() {
return mDescription;
}
+ @UnsupportedAppUsage
public int getUid() {
return mUid;
}
@@ -411,6 +421,7 @@
return mService.loadIcon(pm);
}
+ @UnsupportedAppUsage
public Drawable loadBanner(PackageManager pm) {
Resources res;
try {
@@ -426,6 +437,7 @@
}
}
+ @UnsupportedAppUsage
public String getSettingsActivityName() { return mSettingsActivityName; }
@Override
@@ -483,6 +495,7 @@
dest.writeString(mSettingsActivityName);
};
+ @UnsupportedAppUsage
public static final Parcelable.Creator<ApduServiceInfo> CREATOR =
new Parcelable.Creator<ApduServiceInfo>() {
@Override
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 662d130..b9d9007 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -406,9 +406,28 @@
public static final native void blockUntilThreadAvailable();
/**
- * Default constructor initializes the object.
+ * Default constructor just initializes the object.
+ *
+ * If you're creating a Binder token (a Binder object without an attached interface),
+ * you should use {@link #Binder(String)} instead.
*/
public Binder() {
+ this(null);
+ }
+
+ /**
+ * Constructor for creating a raw Binder object (token) along with a descriptor.
+ *
+ * The descriptor of binder objects usually specifies the interface they are implementing.
+ * In case of binder tokens, no interface is implemented, and the descriptor can be used
+ * as a sort of tag to help identify the binder token. This will help identify remote
+ * references to these objects more easily when debugging.
+ *
+ * @param descriptor Used to identify the creator of this token, for example the class name.
+ * Instead of creating multiple tokens with the same descriptor, consider adding a suffix to
+ * help identify them.
+ */
+ public Binder(@Nullable String descriptor) {
mObject = getNativeBBinderHolder();
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
@@ -420,6 +439,7 @@
klass.getCanonicalName());
}
}
+ mDescriptor = descriptor;
}
/**
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 7ce7c92..7caf0b1 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -492,10 +492,11 @@
String instructionSet,
String appDataDir,
String invokeWith,
+ String packageName,
String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
- abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
+ abi, instructionSet, appDataDir, invokeWith, packageName, zygoteArgs);
}
/** @hide */
@@ -509,10 +510,11 @@
String instructionSet,
String appDataDir,
String invokeWith,
+ String packageName,
String[] zygoteArgs) {
return WebViewZygote.getProcess().start(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
- abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
+ abi, instructionSet, appDataDir, invokeWith, packageName, zygoteArgs);
}
/**
diff --git a/core/java/android/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java
index 021e72f..067e849 100644
--- a/core/java/android/os/ZygoteProcess.java
+++ b/core/java/android/os/ZygoteProcess.java
@@ -227,12 +227,13 @@
String instructionSet,
String appDataDir,
String invokeWith,
+ String packageName,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
runtimeFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, false /* startChildZygote */,
- zygoteArgs);
+ packageName, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -366,6 +367,7 @@
String appDataDir,
String invokeWith,
boolean startChildZygote,
+ String packageName,
String[] extraArgs)
throws ZygoteStartFailedEx {
ArrayList<String> argsForZygote = new ArrayList<String>();
@@ -426,6 +428,10 @@
argsForZygote.add("--start-child-zygote");
}
+ if (packageName != null) {
+ argsForZygote.add("--package-name=" + packageName);
+ }
+
argsForZygote.add(processClass);
if (extraArgs != null) {
@@ -733,7 +739,7 @@
result = startViaZygote(processClass, niceName, uid, gid,
gids, runtimeFlags, 0 /* mountExternal */, 0 /* targetSdkVersion */, seInfo,
abi, instructionSet, null /* appDataDir */, null /* invokeWith */,
- true /* startChildZygote */, extraArgs);
+ true /* startChildZygote */, null /* packageName */, extraArgs);
} catch (ZygoteStartFailedEx ex) {
throw new RuntimeException("Starting child-zygote through Zygote failed", ex);
}
diff --git a/core/java/android/print/PrintDocumentAdapter.java b/core/java/android/print/PrintDocumentAdapter.java
index 2bb7c2e..d1b6efc 100644
--- a/core/java/android/print/PrintDocumentAdapter.java
+++ b/core/java/android/print/PrintDocumentAdapter.java
@@ -16,6 +16,7 @@
package android.print;
+import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
@@ -260,6 +261,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public WriteResultCallback() {
/* do nothing - hide constructor */
}
@@ -304,6 +306,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public LayoutResultCallback() {
/* do nothing - hide constructor */
}
diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java
index 138477e..41f261b 100644
--- a/core/java/android/print/PrintJobInfo.java
+++ b/core/java/android/print/PrintJobInfo.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
@@ -549,6 +550,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public PrintDocumentInfo getDocumentInfo() {
return mDocumentInfo;
}
@@ -639,6 +641,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Bundle getAdvancedOptions() {
return mAdvancedOptions;
}
diff --git a/core/java/android/print/PrintManager.java b/core/java/android/print/PrintManager.java
index e436bc6..e1ede93 100644
--- a/core/java/android/print/PrintManager.java
+++ b/core/java/android/print/PrintManager.java
@@ -22,6 +22,7 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.Application.ActivityLifecycleCallbacks;
import android.content.ComponentName;
@@ -311,6 +312,7 @@
* @param listener The listener to add.
* @hide
*/
+ @UnsupportedAppUsage
public void addPrintJobStateChangeListener(PrintJobStateChangeListener listener) {
if (mService == null) {
Log.w(LOG_TAG, "Feature android.software.print not available");
diff --git a/core/java/android/print/PrinterId.java b/core/java/android/print/PrinterId.java
index ff9c0df..659e56f 100644
--- a/core/java/android/print/PrinterId.java
+++ b/core/java/android/print/PrinterId.java
@@ -17,6 +17,7 @@
package android.print;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
@@ -57,6 +58,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public @NonNull ComponentName getServiceName() {
return mServiceName;
}
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 4b45e32..9c3a409 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -16,8 +16,11 @@
package android.provider;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.content.ClipData;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentUris;
@@ -25,22 +28,23 @@
import android.content.Context;
import android.content.Intent;
import android.content.UriPermission;
+import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.graphics.Matrix;
-import android.media.MiniThumbFile;
-import android.media.ThumbnailUtils;
+import android.graphics.Point;
import android.net.Uri;
import android.os.Bundle;
+import android.os.CancellationSignal;
import android.os.Environment;
-import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.service.media.CameraPrewarmService;
+import android.util.ArrayMap;
import android.util.Log;
+import com.android.internal.annotations.GuardedBy;
+
import libcore.io.IoUtils;
import java.io.File;
@@ -49,7 +53,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.Arrays;
import java.util.List;
/**
@@ -611,178 +614,79 @@
}
}
+ /** @hide */
+ public static class ThumbnailConstants {
+ public static final int MINI_KIND = 1;
+ public static final int FULL_SCREEN_KIND = 2;
+ public static final int MICRO_KIND = 3;
+
+ public static final Point MINI_SIZE = new Point(512, 384);
+ public static final Point MICRO_SIZE = new Point(96, 96);
+ }
+
/**
* This class is used internally by Images.Thumbnails and Video.Thumbnails, it's not intended
* to be accessed elsewhere.
*/
private static class InternalThumbnails implements BaseColumns {
- private static final int MINI_KIND = 1;
- private static final int FULL_SCREEN_KIND = 2;
- private static final int MICRO_KIND = 3;
- private static final String[] PROJECTION = new String[] {_ID, MediaColumns.DATA};
- static final int DEFAULT_GROUP_ID = 0;
- private static final Object sThumbBufLock = new Object();
- private static byte[] sThumbBuf;
-
- private static Bitmap getMiniThumbFromFile(
- Cursor c, Uri baseUri, ContentResolver cr, BitmapFactory.Options options) {
- Bitmap bitmap = null;
- Uri thumbUri = null;
- try {
- long thumbId = c.getLong(0);
- String filePath = c.getString(1);
- thumbUri = ContentUris.withAppendedId(baseUri, thumbId);
- ParcelFileDescriptor pfdInput = cr.openFileDescriptor(thumbUri, "r");
- bitmap = BitmapFactory.decodeFileDescriptor(
- pfdInput.getFileDescriptor(), null, options);
- pfdInput.close();
- } catch (FileNotFoundException ex) {
- Log.e(TAG, "couldn't open thumbnail " + thumbUri + "; " + ex);
- } catch (IOException ex) {
- Log.e(TAG, "couldn't open thumbnail " + thumbUri + "; " + ex);
- } catch (OutOfMemoryError ex) {
- Log.e(TAG, "failed to allocate memory for thumbnail "
- + thumbUri + "; " + ex);
- }
- return bitmap;
- }
+ /**
+ * Currently outstanding thumbnail requests that can be cancelled.
+ */
+ @GuardedBy("sPending")
+ private static ArrayMap<Uri, CancellationSignal> sPending = new ArrayMap<>();
/**
- * This method cancels the thumbnail request so clients waiting for getThumbnail will be
- * interrupted and return immediately. Only the original process which made the getThumbnail
- * requests can cancel their own requests.
+ * Make a blocking request to obtain the given thumbnail, generating it
+ * if needed.
*
- * @param cr ContentResolver
- * @param origId original image or video id. use -1 to cancel all requests.
- * @param groupId the same groupId used in getThumbnail
- * @param baseUri the base URI of requested thumbnails
+ * @see #cancelThumbnail(ContentResolver, Uri)
*/
- static void cancelThumbnailRequest(ContentResolver cr, long origId, Uri baseUri,
- long groupId) {
- Uri cancelUri = baseUri.buildUpon().appendQueryParameter("cancel", "1")
- .appendQueryParameter("orig_id", String.valueOf(origId))
- .appendQueryParameter("group_id", String.valueOf(groupId)).build();
- Cursor c = null;
- try {
- c = cr.query(cancelUri, PROJECTION, null, null, null);
+ static @Nullable Bitmap getThumbnail(@NonNull ContentResolver cr, @NonNull Uri uri,
+ int kind, @Nullable BitmapFactory.Options opts) {
+ final Bundle openOpts = new Bundle();
+ if (kind == ThumbnailConstants.MICRO_KIND) {
+ openOpts.putParcelable(ContentResolver.EXTRA_SIZE, ThumbnailConstants.MICRO_SIZE);
+ } else if (kind == ThumbnailConstants.MINI_KIND) {
+ openOpts.putParcelable(ContentResolver.EXTRA_SIZE, ThumbnailConstants.MINI_SIZE);
+ } else {
+ throw new IllegalArgumentException("Unsupported kind: " + kind);
}
- finally {
- if (c != null) c.close();
+
+ CancellationSignal signal = null;
+ synchronized (sPending) {
+ signal = sPending.get(uri);
+ if (signal == null) {
+ signal = new CancellationSignal();
+ sPending.put(uri, signal);
+ }
}
- }
- /**
- * This method ensure thumbnails associated with origId are generated and decode the byte
- * stream from database (MICRO_KIND) or file (MINI_KIND).
- *
- * Special optimization has been done to avoid further IPC communication for MICRO_KIND
- * thumbnails.
- *
- * @param cr ContentResolver
- * @param origId original image or video id
- * @param kind could be MINI_KIND or MICRO_KIND
- * @param options this is only used for MINI_KIND when decoding the Bitmap
- * @param baseUri the base URI of requested thumbnails
- * @param groupId the id of group to which this request belongs
- * @return Bitmap bitmap of specified thumbnail kind
- */
- static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId, int kind,
- BitmapFactory.Options options, Uri baseUri, boolean isVideo) {
- Bitmap bitmap = null;
- // Log.v(TAG, "getThumbnail: origId="+origId+", kind="+kind+", isVideo="+isVideo);
- // If the magic is non-zero, we simply return thumbnail if it does exist.
- // querying MediaProvider and simply return thumbnail.
- MiniThumbFile thumbFile = MiniThumbFile.instance(
- isVideo ? Video.Media.EXTERNAL_CONTENT_URI : Images.Media.EXTERNAL_CONTENT_URI);
- Cursor c = null;
- try {
- long magic = thumbFile.getMagic(origId);
- if (magic != 0) {
- if (kind == MICRO_KIND) {
- synchronized (sThumbBufLock) {
- if (sThumbBuf == null) {
- sThumbBuf = new byte[MiniThumbFile.BYTES_PER_MINTHUMB];
- }
- if (thumbFile.getMiniThumbFromFile(origId, sThumbBuf) != null) {
- bitmap = BitmapFactory.decodeByteArray(sThumbBuf, 0, sThumbBuf.length);
- if (bitmap == null) {
- Log.w(TAG, "couldn't decode byte array.");
- }
- }
- }
- return bitmap;
- } else if (kind == MINI_KIND) {
- String column = isVideo ? "video_id=" : "image_id=";
- c = cr.query(baseUri, PROJECTION, column + origId, null, null);
- if (c != null && c.moveToFirst()) {
- bitmap = getMiniThumbFromFile(c, baseUri, cr, options);
- if (bitmap != null) {
- return bitmap;
- }
- }
- }
- }
-
- Uri blockingUri = baseUri.buildUpon().appendQueryParameter("blocking", "1")
- .appendQueryParameter("orig_id", String.valueOf(origId))
- .appendQueryParameter("group_id", String.valueOf(groupId)).build();
- if (c != null) c.close();
- c = cr.query(blockingUri, PROJECTION, null, null, null);
- // This happens when original image/video doesn't exist.
- if (c == null) return null;
-
- // Assuming thumbnail has been generated, at least original image exists.
- if (kind == MICRO_KIND) {
- synchronized (sThumbBufLock) {
- if (sThumbBuf == null) {
- sThumbBuf = new byte[MiniThumbFile.BYTES_PER_MINTHUMB];
- }
- Arrays.fill(sThumbBuf, (byte)0);
- if (thumbFile.getMiniThumbFromFile(origId, sThumbBuf) != null) {
- bitmap = BitmapFactory.decodeByteArray(sThumbBuf, 0, sThumbBuf.length);
- if (bitmap == null) {
- Log.w(TAG, "couldn't decode byte array.");
- }
- }
- }
- } else if (kind == MINI_KIND) {
- if (c.moveToFirst()) {
- bitmap = getMiniThumbFromFile(c, baseUri, cr, options);
- }
- } else {
- throw new IllegalArgumentException("Unsupported kind: " + kind);
- }
-
- // We probably run out of space, so create the thumbnail in memory.
- if (bitmap == null) {
- Log.v(TAG, "Create the thumbnail in memory: origId=" + origId
- + ", kind=" + kind + ", isVideo="+isVideo);
- Uri uri = Uri.parse(
- baseUri.buildUpon().appendPath(String.valueOf(origId))
- .toString().replaceFirst("thumbnails", "media"));
- if (c != null) c.close();
- c = cr.query(uri, PROJECTION, null, null, null);
- if (c == null || !c.moveToFirst()) {
- return null;
- }
- String filePath = c.getString(1);
- if (filePath != null) {
- if (isVideo) {
- bitmap = ThumbnailUtils.createVideoThumbnail(filePath, kind);
- } else {
- bitmap = ThumbnailUtils.createImageThumbnail(filePath, kind);
- }
- }
- }
- } catch (SQLiteException ex) {
- Log.w(TAG, ex);
+ try (AssetFileDescriptor afd = cr.openTypedAssetFileDescriptor(uri,
+ "image/*", openOpts, signal)) {
+ return BitmapFactory.decodeFileDescriptor(afd.getFileDescriptor(), null, opts);
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to obtain thumbnail for " + uri, e);
+ return null;
} finally {
- if (c != null) c.close();
- // To avoid file descriptor leak in application process.
- thumbFile.deactivate();
- thumbFile = null;
+ synchronized (sPending) {
+ sPending.remove(uri);
+ }
}
- return bitmap;
+ }
+
+ /**
+ * This method cancels the thumbnail request so clients waiting for
+ * {@link #getThumbnail} will be interrupted and return immediately.
+ * Only the original process which made the request can cancel their own
+ * requests.
+ */
+ static void cancelThumbnail(@NonNull ContentResolver cr, @NonNull Uri uri) {
+ synchronized (sPending) {
+ final CancellationSignal signal = sPending.get(uri);
+ if (signal != null) {
+ signal.cancel();
+ }
+ }
}
}
@@ -916,48 +820,6 @@
}
}
- private static final Bitmap StoreThumbnail(
- ContentResolver cr,
- Bitmap source,
- long id,
- float width, float height,
- int kind) {
- // create the matrix to scale it
- Matrix matrix = new Matrix();
-
- float scaleX = width / source.getWidth();
- float scaleY = height / source.getHeight();
-
- matrix.setScale(scaleX, scaleY);
-
- Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
- source.getWidth(),
- source.getHeight(), matrix,
- true);
-
- ContentValues values = new ContentValues(4);
- values.put(Images.Thumbnails.KIND, kind);
- values.put(Images.Thumbnails.IMAGE_ID, (int)id);
- values.put(Images.Thumbnails.HEIGHT, thumb.getHeight());
- values.put(Images.Thumbnails.WIDTH, thumb.getWidth());
-
- Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values);
-
- try {
- OutputStream thumbOut = cr.openOutputStream(url);
-
- thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
- thumbOut.close();
- return thumb;
- }
- catch (FileNotFoundException ex) {
- return null;
- }
- catch (IOException ex) {
- return null;
- }
- }
-
/**
* Insert an image and create a thumbnail for it.
*
@@ -990,12 +852,9 @@
}
long id = ContentUris.parseId(url);
- // Wait until MINI_KIND thumbnail is generated.
- Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id,
- Images.Thumbnails.MINI_KIND, null);
- // This is for backward compatibility.
- Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F,
- Images.Thumbnails.MICRO_KIND);
+ // Block until we've generated common thumbnails
+ Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null);
+ Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MICRO_KIND, null);
} else {
Log.e(TAG, "Failed to create thumbnail, removing original");
cr.delete(url, null, null);
@@ -1085,8 +944,9 @@
* @param origId original image id
*/
public static void cancelThumbnailRequest(ContentResolver cr, long origId) {
- InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI,
- InternalThumbnails.DEFAULT_GROUP_ID);
+ final Uri uri = ContentUris.withAppendedId(
+ Images.Media.EXTERNAL_CONTENT_URI, origId);
+ InternalThumbnails.cancelThumbnail(cr, uri);
}
/**
@@ -1102,9 +962,9 @@
*/
public static Bitmap getThumbnail(ContentResolver cr, long origId, int kind,
BitmapFactory.Options options) {
- return InternalThumbnails.getThumbnail(cr, origId,
- InternalThumbnails.DEFAULT_GROUP_ID, kind, options,
- EXTERNAL_CONTENT_URI, false);
+ final Uri uri = ContentUris.withAppendedId(
+ Images.Media.EXTERNAL_CONTENT_URI, origId);
+ return InternalThumbnails.getThumbnail(cr, uri, kind, options);
}
/**
@@ -1117,7 +977,7 @@
* @param groupId the same groupId used in getThumbnail.
*/
public static void cancelThumbnailRequest(ContentResolver cr, long origId, long groupId) {
- InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI, groupId);
+ cancelThumbnailRequest(cr, origId);
}
/**
@@ -1134,8 +994,7 @@
*/
public static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId,
int kind, BitmapFactory.Options options) {
- return InternalThumbnails.getThumbnail(cr, origId, groupId, kind, options,
- EXTERNAL_CONTENT_URI, false);
+ return getThumbnail(cr, origId, kind, options);
}
/**
@@ -1193,9 +1052,9 @@
*/
public static final String KIND = "kind";
- public static final int MINI_KIND = 1;
- public static final int FULL_SCREEN_KIND = 2;
- public static final int MICRO_KIND = 3;
+ public static final int MINI_KIND = ThumbnailConstants.MINI_KIND;
+ public static final int FULL_SCREEN_KIND = ThumbnailConstants.FULL_SCREEN_KIND;
+ public static final int MICRO_KIND = ThumbnailConstants.MICRO_KIND;
/**
* The blob raw data of thumbnail
* <P>Type: DATA STREAM</P>
@@ -2155,8 +2014,9 @@
* @param origId original video id
*/
public static void cancelThumbnailRequest(ContentResolver cr, long origId) {
- InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI,
- InternalThumbnails.DEFAULT_GROUP_ID);
+ final Uri uri = ContentUris.withAppendedId(
+ Video.Media.EXTERNAL_CONTENT_URI, origId);
+ InternalThumbnails.cancelThumbnail(cr, uri);
}
/**
@@ -2172,9 +2032,9 @@
*/
public static Bitmap getThumbnail(ContentResolver cr, long origId, int kind,
BitmapFactory.Options options) {
- return InternalThumbnails.getThumbnail(cr, origId,
- InternalThumbnails.DEFAULT_GROUP_ID, kind, options,
- EXTERNAL_CONTENT_URI, true);
+ final Uri uri = ContentUris.withAppendedId(
+ Video.Media.EXTERNAL_CONTENT_URI, origId);
+ return InternalThumbnails.getThumbnail(cr, uri, kind, options);
}
/**
@@ -2191,8 +2051,7 @@
*/
public static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId,
int kind, BitmapFactory.Options options) {
- return InternalThumbnails.getThumbnail(cr, origId, groupId, kind, options,
- EXTERNAL_CONTENT_URI, true);
+ return getThumbnail(cr, origId, kind, options);
}
/**
@@ -2205,7 +2064,7 @@
* @param groupId the same groupId used in getThumbnail.
*/
public static void cancelThumbnailRequest(ContentResolver cr, long origId, long groupId) {
- InternalThumbnails.cancelThumbnailRequest(cr, origId, EXTERNAL_CONTENT_URI, groupId);
+ cancelThumbnailRequest(cr, origId);
}
/**
@@ -2263,9 +2122,9 @@
*/
public static final String KIND = "kind";
- public static final int MINI_KIND = 1;
- public static final int FULL_SCREEN_KIND = 2;
- public static final int MICRO_KIND = 3;
+ public static final int MINI_KIND = ThumbnailConstants.MINI_KIND;
+ public static final int FULL_SCREEN_KIND = ThumbnailConstants.FULL_SCREEN_KIND;
+ public static final int MICRO_KIND = ThumbnailConstants.MICRO_KIND;
/**
* The width of the thumbnal
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ebd90bd..6cf67de 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6031,6 +6031,57 @@
NON_NEGATIVE_INTEGER_VALIDATOR;
/**
+ * Whether to play a sound for charging events.
+ * @hide
+ */
+ public static final String CHARGING_SOUNDS_ENABLED = "charging_sounds_enabled";
+
+ /**
+ * Whether to vibrate for wireless charging events.
+ * @hide
+ */
+ public static final String CHARGING_VIBRATION_ENABLED = "charging_vibration_enabled";
+
+ /**
+ * If 0, turning on dnd manually will last indefinitely.
+ * Else if non-negative, turning on dnd manually will last for this many minutes.
+ * Else (if negative), turning on dnd manually will surface a dialog that prompts
+ * user to specify a duration.
+ * @hide
+ */
+ public static final String ZEN_DURATION = "zen_duration";
+
+ private static final Validator ZEN_DURATION_VALIDATOR = ANY_INTEGER_VALIDATOR;
+
+ /** @hide */ public static final int ZEN_DURATION_PROMPT = -1;
+ /** @hide */ public static final int ZEN_DURATION_FOREVER = 0;
+
+ /**
+ * If nonzero, will show the zen upgrade notification when the user toggles DND on/off.
+ * @hide
+ */
+ public static final String SHOW_ZEN_UPGRADE_NOTIFICATION = "show_zen_upgrade_notification";
+
+ /**
+ * If nonzero, will show the zen update settings suggestion.
+ * @hide
+ */
+ public static final String SHOW_ZEN_SETTINGS_SUGGESTION = "show_zen_settings_suggestion";
+
+ /**
+ * If nonzero, zen has not been updated to reflect new changes.
+ * @hide
+ */
+ public static final String ZEN_SETTINGS_UPDATED = "zen_settings_updated";
+
+ /**
+ * If nonzero, zen setting suggestion has been viewed by user
+ * @hide
+ */
+ public static final String ZEN_SETTINGS_SUGGESTION_VIEWED =
+ "zen_settings_suggestion_viewed";
+
+ /**
* Whether the in call notification is enabled to play sound during calls. The value is
* boolean (1 or 0).
* @hide
@@ -8033,6 +8084,13 @@
IN_CALL_NOTIFICATION_ENABLED,
LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ ZEN_DURATION,
+ SHOW_ZEN_UPGRADE_NOTIFICATION,
+ SHOW_ZEN_SETTINGS_SUGGESTION,
+ ZEN_SETTINGS_UPDATED,
+ ZEN_SETTINGS_SUGGESTION_VIEWED,
+ CHARGING_SOUNDS_ENABLED,
+ CHARGING_VIBRATION_ENABLED,
};
/**
@@ -8178,6 +8236,13 @@
VALIDATORS.put(IN_CALL_NOTIFICATION_ENABLED, IN_CALL_NOTIFICATION_ENABLED_VALIDATOR);
VALIDATORS.put(LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, BOOLEAN_VALIDATOR);
VALIDATORS.put(LOCK_SCREEN_SHOW_NOTIFICATIONS, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(ZEN_DURATION, ZEN_DURATION_VALIDATOR);
+ VALIDATORS.put(SHOW_ZEN_UPGRADE_NOTIFICATION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(SHOW_ZEN_SETTINGS_SUGGESTION, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(ZEN_SETTINGS_UPDATED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(ZEN_SETTINGS_SUGGESTION_VIEWED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(CHARGING_SOUNDS_ENABLED, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(CHARGING_VIBRATION_ENABLED, BOOLEAN_VALIDATOR);
}
/**
@@ -8651,16 +8716,20 @@
/**
* Whether to play a sound for charging events.
+ * @deprecated Use {@link android.provider.Settings.Secure#CHARGING_SOUNDS_ENABLED} instead
* @hide
*/
+ @Deprecated
public static final String CHARGING_SOUNDS_ENABLED = "charging_sounds_enabled";
private static final Validator CHARGING_SOUNDS_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
/**
* Whether to vibrate for wireless charging events.
+ * @deprecated Use {@link android.provider.Settings.Secure#CHARGING_VIBRATION_ENABLED}
* @hide
*/
+ @Deprecated
public static final String CHARGING_VIBRATION_ENABLED = "charging_vibration_enabled";
private static final Validator CHARGING_VIBRATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
@@ -9148,6 +9217,19 @@
/** {@hide} */
public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
+ /**
+ * Whether or not Settings should enable psd API.
+ * {@hide}
+ */
+ public static final String SETTINGS_USE_PSD_API = "settings_use_psd_api";
+
+ /**
+ * Whether or not Settings should enable external provider API.
+ * {@hide}
+ */
+ public static final String SETTINGS_USE_EXTERNAL_PROVIDER_API =
+ "settings_use_external_provider_api";
+
/**
* Sample validity in seconds to configure for the system DNS resolver.
* {@hide}
@@ -9755,6 +9837,18 @@
"recommended_network_evaluator_cache_expiry_ms";
/**
+ * Whether wifi scan throttle is enabled or not.
+ * This is intended to be used via adb commands or a menu in developer option to turn off
+ * the default wifi scan throttling mechanism for apps.
+ *
+ * Type: int (0 for false, 1 for true)
+ * @hide
+ */
+ public static final String WIFI_SCAN_THROTTLE_ENABLED = "wifi_scan_throttle_enabled";
+
+ private static final Validator WIFI_SCAN_THROTTLE_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
* Settings to allow BLE scans to be enabled even when Bluetooth is turned off for
* connectivity.
* @hide
@@ -11721,18 +11815,27 @@
public static final String ZEN_MODE_CONFIG_ETAG = "zen_mode_config_etag";
/**
- * If 0, turning on dnd manually will last indefinitely.
- * Else if non-negative, turning on dnd manually will last for this many minutes.
- * Else (if negative), turning on dnd manually will surface a dialog that prompts
- * user to specify a duration.
+ * @deprecated Use {@link android.provider.Settings.Secure#ZEN_DURATION} instead
* @hide
*/
+ @Deprecated
public static final String ZEN_DURATION = "zen_duration";
private static final Validator ZEN_DURATION_VALIDATOR = ANY_INTEGER_VALIDATOR;
- /** @hide */ public static final int ZEN_DURATION_PROMPT = -1;
- /** @hide */ public static final int ZEN_DURATION_FOREVER = 0;
+ /**
+ * @deprecated Use {@link android.provider.Settings.Secure#ZEN_DURATION_PROMPT} instead
+ * @hide
+ */
+ @Deprecated
+ public static final int ZEN_DURATION_PROMPT = -1;
+
+ /**
+ * @deprecated Use {@link android.provider.Settings.Secure#ZEN_DURATION_FOREVER} instead
+ * @hide
+ */
+ @Deprecated
+ public static final int ZEN_DURATION_FOREVER = 0;
/**
* Defines global heads up toggle. One of HEADS_UP_OFF, HEADS_UP_ON.
@@ -12237,6 +12340,7 @@
VALIDATORS.put(SOFT_AP_TIMEOUT_ENABLED, SOFT_AP_TIMEOUT_ENABLED_VALIDATOR);
VALIDATORS.put(WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON,
WIFI_CARRIER_NETWORKS_AVAILABLE_NOTIFICATION_ON_VALIDATOR);
+ VALIDATORS.put(WIFI_SCAN_THROTTLE_ENABLED, WIFI_SCAN_THROTTLE_ENABLED_VALIDATOR);
VALIDATORS.put(APP_AUTO_RESTRICTION_ENABLED, APP_AUTO_RESTRICTION_ENABLED_VALIDATOR);
VALIDATORS.put(ZEN_DURATION, ZEN_DURATION_VALIDATOR);
VALIDATORS.put(CHARGING_VIBRATION_ENABLED, CHARGING_VIBRATION_ENABLED_VALIDATOR);
@@ -12276,8 +12380,16 @@
// Certain settings have been moved from global to the per-user secure namespace
private static final HashSet<String> MOVED_TO_SECURE;
static {
- MOVED_TO_SECURE = new HashSet<>(1);
- MOVED_TO_SECURE.add(Settings.Global.INSTALL_NON_MARKET_APPS);
+ MOVED_TO_SECURE = new HashSet<>(8);
+ MOVED_TO_SECURE.add(Global.INSTALL_NON_MARKET_APPS);
+ MOVED_TO_SECURE.add(Global.ZEN_DURATION);
+ MOVED_TO_SECURE.add(Global.SHOW_ZEN_UPGRADE_NOTIFICATION);
+ MOVED_TO_SECURE.add(Global.SHOW_ZEN_SETTINGS_SUGGESTION);
+ MOVED_TO_SECURE.add(Global.ZEN_SETTINGS_UPDATED);
+ MOVED_TO_SECURE.add(Global.ZEN_SETTINGS_SUGGESTION_VIEWED);
+ MOVED_TO_SECURE.add(Global.CHARGING_SOUNDS_ENABLED);
+ MOVED_TO_SECURE.add(Global.CHARGING_VIBRATION_ENABLED);
+
}
/** @hide */
@@ -12953,28 +13065,37 @@
*/
public static final String SHOW_MUTE_IN_CRASH_DIALOG = "show_mute_in_crash_dialog";
+
/**
* If nonzero, will show the zen upgrade notification when the user toggles DND on/off.
* @hide
+ * @deprecated - Use {@link android.provider.Settings.Secure#SHOW_ZEN_UPGRADE_NOTIFICATION}
*/
+ @Deprecated
public static final String SHOW_ZEN_UPGRADE_NOTIFICATION = "show_zen_upgrade_notification";
/**
* If nonzero, will show the zen update settings suggestion.
* @hide
+ * @deprecated - Use {@link android.provider.Settings.Secure#SHOW_ZEN_SETTINGS_SUGGESTION}
*/
+ @Deprecated
public static final String SHOW_ZEN_SETTINGS_SUGGESTION = "show_zen_settings_suggestion";
/**
* If nonzero, zen has not been updated to reflect new changes.
+ * @deprecated - Use {@link android.provider.Settings.Secure#ZEN_SETTINGS_UPDATED}
* @hide
*/
+ @Deprecated
public static final String ZEN_SETTINGS_UPDATED = "zen_settings_updated";
/**
- * If nonzero, zen setting suggestion has beem viewed by user
+ * If nonzero, zen setting suggestion has been viewed by user
* @hide
+ * @deprecated - Use {@link android.provider.Settings.Secure#ZEN_SETTINGS_SUGGESTION_VIEWED}
*/
+ @Deprecated
public static final String ZEN_SETTINGS_SUGGESTION_VIEWED =
"zen_settings_suggestion_viewed";
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index 1cd76d2..e5e1c92 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -65,16 +65,36 @@
/**
* Manifest metadata key for the resource string containing the name of the default field
* classification algorithm.
+ *
+ * @deprecated Use {@link #RESOURCE_DEFAULT_ALGORITHM} instead.
*/
+ @Deprecated
public static final String SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM =
"android.autofill.field_classification.default_algorithm";
+
/**
* Manifest metadata key for the resource string array containing the names of all field
* classification algorithms provided by the service.
+ *
+ * @deprecated Use {@link #RESOURCE_AVAILABLE_ALGORITHMS} instead.
*/
+ @Deprecated
public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS =
"android.autofill.field_classification.available_algorithms";
+ /**
+ * Name of the resource string containing the name of the default field
+ * classification algorithm.
+ */
+ public static final String RESOURCE_DEFAULT_ALGORITHM =
+ "autofill_field_classification_default_algorithm";
+
+ /**
+ * Name of the resource string array containing the names of all field
+ * classification algorithms provided by the service.
+ */
+ public static final String RESOURCE_AVAILABLE_ALGORITHMS =
+ "autofill_field_classification_available_algorithms";
/** {@hide} **/
public static final String EXTRA_SCORES = "scores";
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 0d94af4..e0c354a 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -71,6 +71,12 @@
public static final String KEY_SMART_ACTIONS = "key_smart_actions";
/**
+ * Data type: ArrayList of {@link CharSequence}.
+ * Used to suggest smart replies for a notification.
+ */
+ public static final String KEY_SMART_REPLIES = "key_smart_replies";
+
+ /**
* Create a notification adjustment.
*
* @param pkg The package of the notification.
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 18e0ab0..81889c1 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -19,6 +19,8 @@
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.annotation.TestApi;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
@@ -34,6 +36,22 @@
/**
* A service that helps the user manage notifications.
+ * <p>
+ * Only one notification assistant can be active at a time. Unlike notification listener services,
+ * assistant services can additionally modify certain aspects about notifications
+ * (see {@link Adjustment}) before they are posted.
+ *<p>
+ * A note about managed profiles: Unlike {@link NotificationListenerService listener services},
+ * NotificationAssistantServices are allowed to run in managed profiles
+ * (see {@link DevicePolicyManager#isManagedProfile(ComponentName)}), so they can access the
+ * information they need to create good {@link Adjustment adjustments}. To maintain the contract
+ * with {@link NotificationListenerService}, an assistant service will receive all of the
+ * callbacks from {@link NotificationListenerService} for the current user, managed profiles of
+ * that user, and ones that affect all users. However,
+ * {@link #onNotificationEnqueued(StatusBarNotification)} will only be called for notifications
+ * sent to the current user, and {@link Adjustment adjuments} will only be accepted for the
+ * current user.
+ *
* @hide
*/
@SystemApi
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 09425a9..09eecd8 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -1427,6 +1427,7 @@
private @UserSentiment int mUserSentiment = USER_SENTIMENT_NEUTRAL;
private boolean mHidden;
private ArrayList<Notification.Action> mSmartActions;
+ private ArrayList<CharSequence> mSmartReplies;
public Ranking() {}
@@ -1564,6 +1565,13 @@
}
/**
+ * @hide
+ */
+ public List<CharSequence> getSmartReplies() {
+ return mSmartReplies;
+ }
+
+ /**
* Returns whether this notification can be displayed as a badge.
*
* @return true if the notification can be displayed as a badge, false otherwise.
@@ -1591,7 +1599,8 @@
CharSequence explanation, String overrideGroupKey,
NotificationChannel channel, ArrayList<String> overridePeople,
ArrayList<SnoozeCriterion> snoozeCriteria, boolean showBadge,
- int userSentiment, boolean hidden, ArrayList<Notification.Action> smartActions) {
+ int userSentiment, boolean hidden, ArrayList<Notification.Action> smartActions,
+ ArrayList<CharSequence> smartReplies) {
mKey = key;
mRank = rank;
mIsAmbient = importance < NotificationManager.IMPORTANCE_LOW;
@@ -1608,6 +1617,7 @@
mUserSentiment = userSentiment;
mHidden = hidden;
mSmartActions = smartActions;
+ mSmartReplies = smartReplies;
}
/**
@@ -1658,6 +1668,7 @@
private ArrayMap<String, Integer> mUserSentiment;
private ArrayMap<String, Boolean> mHidden;
private ArrayMap<String, ArrayList<Notification.Action>> mSmartActions;
+ private ArrayMap<String, ArrayList<CharSequence>> mSmartReplies;
private RankingMap(NotificationRankingUpdate rankingUpdate) {
mRankingUpdate = rankingUpdate;
@@ -1686,7 +1697,8 @@
getVisibilityOverride(key), getSuppressedVisualEffects(key),
getImportance(key), getImportanceExplanation(key), getOverrideGroupKey(key),
getChannel(key), getOverridePeople(key), getSnoozeCriteria(key),
- getShowBadge(key), getUserSentiment(key), getHidden(key), getSmartActions(key));
+ getShowBadge(key), getUserSentiment(key), getHidden(key), getSmartActions(key),
+ getSmartReplies(key));
return rank >= 0;
}
@@ -1833,6 +1845,15 @@
return mSmartActions.get(key);
}
+ private ArrayList<CharSequence> getSmartReplies(String key) {
+ synchronized (this) {
+ if (mSmartReplies == null) {
+ buildSmartReplies();
+ }
+ }
+ return mSmartReplies.get(key);
+ }
+
// Locked by 'this'
private void buildRanksLocked() {
String[] orderedKeys = mRankingUpdate.getOrderedKeys();
@@ -1959,6 +1980,15 @@
}
}
+ // Locked by 'this'
+ private void buildSmartReplies() {
+ Bundle smartReplies = mRankingUpdate.getSmartReplies();
+ mSmartReplies = new ArrayMap<>(smartReplies.size());
+ for (String key : smartReplies.keySet()) {
+ mSmartReplies.put(key, smartReplies.getCharSequenceArrayList(key));
+ }
+ }
+
// ----------- Parcelable
@Override
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index bed22149..c67fad0 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -38,12 +38,14 @@
private final Bundle mUserSentiment;
private final Bundle mHidden;
private final Bundle mSmartActions;
+ private final Bundle mSmartReplies;
public NotificationRankingUpdate(String[] keys, String[] interceptedKeys,
Bundle visibilityOverrides, Bundle suppressedVisualEffects,
int[] importance, Bundle explanation, Bundle overrideGroupKeys,
Bundle channels, Bundle overridePeople, Bundle snoozeCriteria,
- Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions) {
+ Bundle showBadge, Bundle userSentiment, Bundle hidden, Bundle smartActions,
+ Bundle smartReplies) {
mKeys = keys;
mInterceptedKeys = interceptedKeys;
mVisibilityOverrides = visibilityOverrides;
@@ -58,6 +60,7 @@
mUserSentiment = userSentiment;
mHidden = hidden;
mSmartActions = smartActions;
+ mSmartReplies = smartReplies;
}
public NotificationRankingUpdate(Parcel in) {
@@ -76,6 +79,7 @@
mUserSentiment = in.readBundle();
mHidden = in.readBundle();
mSmartActions = in.readBundle();
+ mSmartReplies = in.readBundle();
}
@Override
@@ -99,6 +103,7 @@
out.writeBundle(mUserSentiment);
out.writeBundle(mHidden);
out.writeBundle(mSmartActions);
+ out.writeBundle(mSmartReplies);
}
public static final Parcelable.Creator<NotificationRankingUpdate> CREATOR
@@ -167,4 +172,8 @@
public Bundle getSmartActions() {
return mSmartActions;
}
+
+ public Bundle getSmartReplies() {
+ return mSmartReplies;
+ }
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index c48b6d1..29f73b5 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -21,6 +21,7 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.app.Service;
import android.app.WallpaperColors;
+import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
@@ -436,8 +437,7 @@
/**
* Returns true if this engine is running in ambient mode -- that is,
- * it is being shown in low power mode, in always on display.
- * @hide
+ * it is being shown in low power mode, on always on display.
*/
public boolean isInAmbientMode() {
return mIsInAmbientMode;
@@ -563,10 +563,12 @@
* Called when the device enters or exits ambient mode.
*
* @param inAmbientMode {@code true} if in ambient mode.
- * @param animated {@code true} if you'll have te opportunity of animating your transition
- * {@code false} when the screen will blank and the wallpaper should be
- * set to ambient mode immediately.
- * @hide
+ * @param animated {@code true} if you'll have the opportunity of animating your transition
+ * {@code false} when the wallpaper should present its ambient version
+ * immediately.
+ *
+ * @see #isInAmbientMode()
+ * @see WallpaperInfo#supportsAmbientMode()
*/
public void onAmbientModeChanged(boolean inAmbientMode, boolean animated) {
}
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 2499afb..1b063e1 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -380,8 +380,8 @@
/** @hide */ public static final int LOG_ID_SYSTEM = 3;
/** @hide */ public static final int LOG_ID_CRASH = 4;
- /** @hide */ public static native int println_native(int bufID,
- int priority, String tag, String msg);
+ /** @hide */
+ public static native int println_native(int bufID, int priority, String tag, String msg);
/**
* Return the maximum payload the log daemon accepts without truncation.
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index b3400ef..af18caa 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -22,32 +22,34 @@
import libcore.util.EmptyArray;
/**
- * SparseArrays map integers to Objects. Unlike a normal array of Objects,
- * there can be gaps in the indices. It is intended to be more memory efficient
- * than using a HashMap to map Integers to Objects, both because it avoids
+ * <code>SparseArray</code> maps integers to Objects and, unlike a normal array of Objects,
+ * its indices can contain gaps. <code>SparseArray</code> is intended to be more memory-efficient
+ * than a
+ * <a href="/reference/java/util/HashMap"><code>HashMap</code></a>, because it avoids
* auto-boxing keys and its data structure doesn't rely on an extra entry object
* for each mapping.
*
* <p>Note that this container keeps its mappings in an array data structure,
- * using a binary search to find keys. The implementation is not intended to be appropriate for
+ * using a binary search to find keys. The implementation is not intended to be appropriate for
* data structures
- * that may contain large numbers of items. It is generally slower than a traditional
- * HashMap, since lookups require a binary search and adds and removes require inserting
- * and deleting entries in the array. For containers holding up to hundreds of items,
- * the performance difference is not significant, less than 50%.</p>
+ * that may contain large numbers of items. It is generally slower than a
+ * <code>HashMap</code> because lookups require a binary search,
+ * and adds and removes require inserting
+ * and deleting entries in the array. For containers holding up to hundreds of items,
+ * the performance difference is less than 50%.
*
* <p>To help with performance, the container includes an optimization when removing
* keys: instead of compacting its array immediately, it leaves the removed entry marked
- * as deleted. The entry can then be re-used for the same key, or compacted later in
- * a single garbage collection step of all removed entries. This garbage collection will
- * need to be performed at any time the array needs to be grown or the the map size or
- * entry values are retrieved.</p>
+ * as deleted. The entry can then be re-used for the same key or compacted later in
+ * a single garbage collection of all removed entries. This garbage collection
+ * must be performed whenever the array needs to be grown, or when the map size or
+ * entry values are retrieved.
*
* <p>It is possible to iterate over the items in this container using
* {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
- * <code>keyAt(int)</code> with ascending values of the index will return the
- * keys in ascending order, or the values corresponding to the keys in ascending
- * order in the case of <code>valueAt(int)</code>.</p>
+ * <code>keyAt(int)</code> with ascending values of the index returns the
+ * keys in ascending order. In the case of <code>valueAt(int)</code>, the
+ * values corresponding to the keys are returned in ascending order.
*/
public class SparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
@@ -333,7 +335,7 @@
/**
* Returns an index for which {@link #valueAt} would return the
- * specified key, or a negative number if no keys map to the
+ * specified value, or a negative number if no keys map to the
* specified value.
* <p>Beware that this is a linear search, unlike lookups by key,
* and that multiple keys can map to the same value and this will
@@ -357,7 +359,7 @@
/**
* Returns an index for which {@link #valueAt} would return the
- * specified key, or a negative number if no keys map to the
+ * specified value, or a negative number if no keys map to the
* specified value.
* <p>Beware that this is a linear search, unlike lookups by key,
* and that multiple keys can map to the same value and this will
diff --git a/core/java/android/view/RecordingCanvas.java b/core/java/android/view/RecordingCanvas.java
index 74fa9e8..3364483 100644
--- a/core/java/android/view/RecordingCanvas.java
+++ b/core/java/android/view/RecordingCanvas.java
@@ -536,9 +536,6 @@
@Nullable int[] colors, int colorOffset, @Nullable short[] indices, int indexOffset,
int indexCount, @NonNull Paint paint) {
checkRange(verts.length, vertOffset, vertexCount);
- if (isHardwareAccelerated()) {
- return;
- }
if (texs != null) {
checkRange(texs.length, texOffset, vertexCount);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 240f3c0..97a2d79 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3097,13 +3097,27 @@
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
boolean usingAsyncReport = false;
- if (mReportNextDraw && mAttachInfo.mThreadedRenderer != null
- && mAttachInfo.mThreadedRenderer.isEnabled()) {
- usingAsyncReport = true;
- mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> {
- // TODO: Use the frame number
- pendingDrawFinished();
- });
+ if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) {
+ ArrayList<Runnable> commitCallbacks = mAttachInfo.mTreeObserver
+ .captureFrameCommitCallbacks();
+ if (mReportNextDraw) {
+ usingAsyncReport = true;
+ mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> {
+ // TODO: Use the frame number
+ pendingDrawFinished();
+ if (commitCallbacks != null) {
+ for (int i = 0; i < commitCallbacks.size(); i++) {
+ commitCallbacks.get(i).run();
+ }
+ }
+ });
+ } else if (commitCallbacks != null && commitCallbacks.size() > 0) {
+ mAttachInfo.mThreadedRenderer.setFrameCompleteCallback((long frameNr) -> {
+ for (int i = 0; i < commitCallbacks.size(); i++) {
+ commitCallbacks.get(i).run();
+ }
+ });
+ }
}
try {
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 0973d0a..efc1807 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -16,6 +16,9 @@
package android.view;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.Region;
@@ -56,6 +59,9 @@
private ArrayList<OnDrawListener> mOnDrawListeners;
private static boolean sIllegalOnDrawModificationIsFatal;
+ // These listeners are one-shot
+ private ArrayList<Runnable> mOnFrameCommitListeners;
+
/** Remains false until #dispatchOnWindowShown() is called. If a listener registers after
* that the listener will be immediately called. */
private boolean mWindowShown;
@@ -393,6 +399,14 @@
}
}
+ if (observer.mOnFrameCommitListeners != null) {
+ if (mOnFrameCommitListeners != null) {
+ mOnFrameCommitListeners.addAll(observer.captureFrameCommitCallbacks());
+ } else {
+ mOnFrameCommitListeners = observer.captureFrameCommitCallbacks();
+ }
+ }
+
if (observer.mOnTouchModeChangeListeners != null) {
if (mOnTouchModeChangeListeners != null) {
mOnTouchModeChangeListeners.addAll(observer.mOnTouchModeChangeListeners);
@@ -713,6 +727,49 @@
}
/**
+ * Adds a frame commit callback. This callback will be invoked when the current rendering
+ * content has been rendered into a frame and submitted to the swap chain. The frame may
+ * not currently be visible on the display when this is invoked, but it has been submitted.
+ * This callback is useful in combination with {@link PixelCopy} to capture the current
+ * rendered content of the UI reliably.
+ *
+ * Note: Only works with hardware rendering. Does nothing otherwise.
+ *
+ * @param callback The callback to invoke when the frame is committed.
+ */
+ @TestApi
+ public void registerFrameCommitCallback(@NonNull Runnable callback) {
+ checkIsAlive();
+ if (mOnFrameCommitListeners == null) {
+ mOnFrameCommitListeners = new ArrayList<>();
+ }
+ mOnFrameCommitListeners.add(callback);
+ }
+
+ @Nullable ArrayList<Runnable> captureFrameCommitCallbacks() {
+ ArrayList<Runnable> ret = mOnFrameCommitListeners;
+ mOnFrameCommitListeners = null;
+ return ret;
+ }
+
+ /**
+ * Attempts to remove the given callback from the list of pending frame complete callbacks.
+ *
+ * @param callback The callback to remove
+ * @return Whether or not the callback was removed. If this returns true the callback will
+ * not be invoked. If false is returned then the callback was either never added
+ * or may already be pending execution and was unable to be removed
+ */
+ @TestApi
+ public boolean unregisterFrameCommitCallback(@NonNull Runnable callback) {
+ checkIsAlive();
+ if (mOnFrameCommitListeners == null) {
+ return false;
+ }
+ return mOnFrameCommitListeners.remove(callback);
+ }
+
+ /**
* Register a callback to be invoked when a view has been scrolled.
*
* @param listener The callback to add
diff --git a/core/java/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index 0e1e379..b4d9c53 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -336,7 +336,13 @@
AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info);
nodes.put(sourceId, clone);
if (clone.isAccessibilityFocused()) {
+ if (mAccessibilityFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
+ && mAccessibilityFocus != sourceId) {
+ refreshCachedNodeLocked(windowId, mAccessibilityFocus);
+ }
mAccessibilityFocus = sourceId;
+ } else if (mAccessibilityFocus == sourceId) {
+ mAccessibilityFocus = AccessibilityNodeInfo.UNDEFINED_ITEM_ID;
}
if (clone.isFocused()) {
mInputFocus = sourceId;
diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java
index 64686dd..87b7b05 100644
--- a/core/java/android/view/animation/Animation.java
+++ b/core/java/android/view/animation/Animation.java
@@ -19,6 +19,7 @@
import android.annotation.AnimRes;
import android.annotation.ColorInt;
import android.annotation.InterpolatorRes;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.RectF;
@@ -183,6 +184,7 @@
/**
* The animation listener to be notified when the animation starts, ends or repeats.
*/
+ @UnsupportedAppUsage
AnimationListener mListener;
/**
@@ -211,9 +213,13 @@
private boolean mMore = true;
private boolean mOneMoreTime = true;
+ @UnsupportedAppUsage
RectF mPreviousRegion = new RectF();
+ @UnsupportedAppUsage
RectF mRegion = new RectF();
+ @UnsupportedAppUsage
Transformation mTransformation = new Transformation();
+ @UnsupportedAppUsage
Transformation mPreviousTransformation = new Transformation();
private final CloseGuard guard = CloseGuard.get();
@@ -322,6 +328,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public void detach() {
if (mStarted && !mEnded) {
mEnded = true;
@@ -1046,6 +1053,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void getInvalidateRegion(int left, int top, int right, int bottom,
RectF invalidate, Transformation transformation) {
@@ -1077,6 +1085,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void initializeInvalidateRegion(int left, int top, int right, int bottom) {
final RectF region = mPreviousRegion;
region.set(left, top, right, bottom);
diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java
index 29f8442..c877b9c 100644
--- a/core/java/android/view/animation/AnimationUtils.java
+++ b/core/java/android/view/animation/AnimationUtils.java
@@ -19,6 +19,7 @@
import android.annotation.AnimRes;
import android.annotation.InterpolatorRes;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
@@ -157,6 +158,7 @@
return createAnimationFromXml(c, parser, null, Xml.asAttributeSet(parser));
}
+ @UnsupportedAppUsage
private static Animation createAnimationFromXml(Context c, XmlPullParser parser,
AnimationSet parent, AttributeSet attrs) throws XmlPullParserException, IOException {
diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java
index 8eb5b5c..58da04d 100644
--- a/core/java/android/view/animation/Transformation.java
+++ b/core/java/android/view/animation/Transformation.java
@@ -17,6 +17,7 @@
package android.view.animation;
import android.annotation.FloatRange;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Matrix;
import android.graphics.Rect;
@@ -238,6 +239,7 @@
* Print short string, to optimize dumping.
* @hide
*/
+ @UnsupportedAppUsage
public void printShortString(PrintWriter pw) {
pw.print("{alpha="); pw.print(mAlpha);
pw.print(" matrix=");
diff --git a/core/java/android/view/animation/TranslateAnimation.java b/core/java/android/view/animation/TranslateAnimation.java
index 216022b..6c040d4 100644
--- a/core/java/android/view/animation/TranslateAnimation.java
+++ b/core/java/android/view/animation/TranslateAnimation.java
@@ -16,6 +16,7 @@
package android.view.animation;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
@@ -34,13 +35,17 @@
private int mToYType = ABSOLUTE;
/** @hide */
+ @UnsupportedAppUsage
protected float mFromXValue = 0.0f;
/** @hide */
+ @UnsupportedAppUsage
protected float mToXValue = 0.0f;
/** @hide */
+ @UnsupportedAppUsage
protected float mFromYValue = 0.0f;
/** @hide */
+ @UnsupportedAppUsage
protected float mToYValue = 0.0f;
/** @hide */
diff --git a/core/java/android/view/animation/TranslateYAnimation.java b/core/java/android/view/animation/TranslateYAnimation.java
index 714558d..a6e0ccb 100644
--- a/core/java/android/view/animation/TranslateYAnimation.java
+++ b/core/java/android/view/animation/TranslateYAnimation.java
@@ -16,6 +16,7 @@
package android.view.animation;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Matrix;
/**
@@ -38,6 +39,7 @@
/**
* Constructor. Passes in 0 for the x parameters of TranslateAnimation
*/
+ @UnsupportedAppUsage
public TranslateYAnimation(int fromYType, float fromYValue, int toYType, float toYValue) {
super(ABSOLUTE, 0, ABSOLUTE, 0, fromYType, fromYValue, toYType, toYValue);
}
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b5c7364..32b2f63 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1405,7 +1405,8 @@
final SyncResultReceiver receiver = new SyncResultReceiver();
try {
mService.getAvailableFieldClassificationAlgorithms(receiver);
- final String[] algorithms = receiver.getObjectResult(SyncResultReceiver.TYPE_STRING);
+ final String[] algorithms = receiver
+ .getObjectResult(SyncResultReceiver.TYPE_STRING_ARRAY);
return algorithms != null ? Arrays.asList(algorithms) : Collections.emptyList();
} catch (RemoteException e) {
e.rethrowFromSystemServer();
@@ -2906,7 +2907,7 @@
case TYPE_STRING:
return (T) mBundle.getString(EXTRA);
case TYPE_STRING_ARRAY:
- return (T) mBundle.getString(EXTRA);
+ return (T) mBundle.getStringArray(EXTRA);
case TYPE_PARCELABLE:
return (T) mBundle.getParcelable(EXTRA);
default:
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index f686b66..bdd7a09 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -31,18 +31,25 @@
public class WebViewClient {
/**
- * Give the host application a chance to take over the control when a new
- * url is about to be loaded in the current WebView. If WebViewClient is not
- * provided, by default WebView will ask Activity Manager to choose the
- * proper handler for the url. If WebViewClient is provided, return {@code true}
- * means the host application handles the url, while return {@code false} means the
- * current WebView handles the url.
- * This method is not called for requests using the POST "method".
+ * Give the host application a chance to take control when a URL is about to be loaded in the
+ * current WebView. If a WebViewClient is not provided, by default WebView will ask Activity
+ * Manager to choose the proper handler for the URL. If a WebViewClient is provided, returning
+ * {@code true} causes the current WebView to abort loading the URL, while returning
+ * {@code false} causes the WebView to continue loading the URL as usual.
+ *
+ * <p class="note"><b>Note:</b> Do not call {@link WebView#loadUrl(String)} with the same
+ * URL and then return {@code true}. This unnecessarily cancels the current load and starts a
+ * new load with the same URL. The correct way to continue loading a given URL is to simply
+ * return {@code false}, without calling {@link WebView#loadUrl(String)}.
+ *
+ * <p class="note"><b>Note:</b> This method is not called for POST requests.
+ *
+ * <p class="note"><b>Note:</b> This method may be called for subframes and with non-HTTP(S)
+ * schemes; calling {@link WebView#loadUrl(String)} with such a URL will fail.
*
* @param view The WebView that is initiating the callback.
- * @param url The url to be loaded.
- * @return {@code true} if the host application wants to leave the current WebView
- * and handle the url itself, otherwise return {@code false}.
+ * @param url The URL to be loaded.
+ * @return {@code true} to cancel the current load, otherwise return {@code false}.
* @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest)
* shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead.
*/
@@ -52,26 +59,25 @@
}
/**
- * Give the host application a chance to take over the control when a new
- * url is about to be loaded in the current WebView. If WebViewClient is not
- * provided, by default WebView will ask Activity Manager to choose the
- * proper handler for the url. If WebViewClient is provided, return {@code true}
- * means the host application handles the url, while return {@code false} means the
- * current WebView handles the url.
+ * Give the host application a chance to take control when a URL is about to be loaded in the
+ * current WebView. If a WebViewClient is not provided, by default WebView will ask Activity
+ * Manager to choose the proper handler for the URL. If a WebViewClient is provided, returning
+ * {@code true} causes the current WebView to abort loading the URL, while returning
+ * {@code false} causes the WebView to continue loading the URL as usual.
*
- * <p>Notes:
- * <ul>
- * <li>This method is not called for requests using the POST "method".</li>
- * <li>This method is also called for subframes with non-http schemes, thus it is
- * strongly disadvised to unconditionally call {@link WebView#loadUrl(String)}
- * with the request's url from inside the method and then return {@code true},
- * as this will make WebView to attempt loading a non-http url, and thus fail.</li>
- * </ul>
+ * <p class="note"><b>Note:</b> Do not call {@link WebView#loadUrl(String)} with the request's
+ * URL and then return {@code true}. This unnecessarily cancels the current load and starts a
+ * new load with the same URL. The correct way to continue loading a given URL is to simply
+ * return {@code false}, without calling {@link WebView#loadUrl(String)}.
+ *
+ * <p class="note"><b>Note:</b> This method is not called for POST requests.
+ *
+ * <p class="note"><b>Note:</b> This method may be called for subframes and with non-HTTP(S)
+ * schemes; calling {@link WebView#loadUrl(String)} with such a URL will fail.
*
* @param view The WebView that is initiating the callback.
* @param request Object containing the details of the request.
- * @return {@code true} if the host application wants to leave the current WebView
- * and handle the url itself, otherwise return {@code false}.
+ * @return {@code true} to cancel the current load, otherwise return {@code false}.
*/
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return shouldOverrideUrlLoading(view, request.getUrl().toString());
diff --git a/core/java/com/android/internal/app/procstats/AssociationState.java b/core/java/com/android/internal/app/procstats/AssociationState.java
index e5d6556..f63c43f 100644
--- a/core/java/com/android/internal/app/procstats/AssociationState.java
+++ b/core/java/com/android/internal/app/procstats/AssociationState.java
@@ -36,7 +36,6 @@
private final ProcessStats.PackageState mPackageState;
private final String mProcessName;
private final String mName;
- private final DurationsTable mDurations;
public final class SourceState {
final SourceKey mKey;
@@ -49,8 +48,10 @@
long mDuration;
long mTrackingUptime;
int mActiveCount;
+ int mActiveProcState = ProcessStats.STATE_NOTHING;
long mActiveStartUptime;
long mActiveDuration;
+ DurationsTable mDurations;
SourceState(SourceKey key) {
mKey = key;
@@ -77,13 +78,15 @@
mProcState = procState;
}
if (procState < ProcessStats.STATE_HOME) {
+ // If the proc state has become better than cached, then we want to
+ // start tracking it to count when it is actually active. If it drops
+ // down to cached, we will clean it up when we later evaluate all currently
+ // tracked associations in ProcessStats.updateTrackingAssociationsLocked().
if (!mInTrackingList) {
mInTrackingList = true;
mTrackingUptime = now;
mProcessStats.mTrackingAssociations.add(this);
}
- } else {
- stopTracking(now);
}
}
@@ -102,6 +105,22 @@
mActiveStartUptime = now;
mActiveCount++;
}
+ if (mActiveProcState != mProcState) {
+ if (mActiveProcState != ProcessStats.STATE_NOTHING) {
+ // Currently active proc state changed, need to store the duration
+ // so far and switch tracking to the new proc state.
+ final long duration = mActiveDuration + now - mActiveStartUptime;
+ if (duration != 0) {
+ if (mDurations == null) {
+ makeDurations();
+ }
+ mDurations.addDuration(mActiveProcState, duration);
+ mActiveDuration = 0;
+ }
+ mActiveStartUptime = now;
+ }
+ mActiveProcState = mProcState;
+ }
} else {
Slog.wtf(TAG, "startActive while not tracking: " + this);
}
@@ -112,15 +131,25 @@
if (!mInTrackingList) {
Slog.wtf(TAG, "stopActive while not tracking: " + this);
}
- mActiveDuration += now - mActiveStartUptime;
+ final long duration = mActiveDuration + now - mActiveStartUptime;
+ if (mDurations != null) {
+ mDurations.addDuration(mActiveProcState, duration);
+ } else {
+ mActiveDuration = duration;
+ }
mActiveStartUptime = 0;
}
}
+ void makeDurations() {
+ mDurations = new DurationsTable(mProcessStats.mTableData);
+ }
+
void stopTracking(long now) {
stopActive(now);
if (mInTrackingList) {
mInTrackingList = false;
+ mProcState = ProcessStats.STATE_NOTHING;
// Do a manual search for where to remove, since these objects will typically
// be towards the end of the array.
final ArrayList<SourceState> list = mProcessStats.mTrackingAssociations;
@@ -207,7 +236,6 @@
mPackageState = packageState;
mName = name;
mProcessName = processName;
- mDurations = new DurationsTable(processStats.mTableData);
mProc = proc;
}
@@ -254,7 +282,6 @@
}
public void add(AssociationState other) {
- mDurations.addDurations(other.mDurations);
for (int isrc = other.mSources.size() - 1; isrc >= 0; isrc--) {
final SourceKey key = other.mSources.keyAt(isrc);
final SourceState otherSrc = other.mSources.valueAt(isrc);
@@ -266,7 +293,48 @@
mySrc.mCount += otherSrc.mCount;
mySrc.mDuration += otherSrc.mDuration;
mySrc.mActiveCount += otherSrc.mActiveCount;
- mySrc.mActiveDuration += otherSrc.mActiveDuration;
+ if (otherSrc.mActiveDuration != 0 || otherSrc.mDurations != null) {
+ // Only need to do anything if the other one has some duration data.
+ if (mySrc.mDurations != null) {
+ // If the target already has multiple durations, just add in whatever
+ // we have in the other.
+ if (otherSrc.mDurations != null) {
+ mySrc.mDurations.addDurations(otherSrc.mDurations);
+ } else {
+ mySrc.mDurations.addDuration(otherSrc.mActiveProcState,
+ otherSrc.mActiveDuration);
+ }
+ } else if (otherSrc.mDurations != null) {
+ // The other one has multiple durations, but we don't. Expand to
+ // multiple durations and copy over.
+ mySrc.makeDurations();
+ mySrc.mDurations.addDurations(otherSrc.mDurations);
+ if (mySrc.mActiveDuration != 0) {
+ mySrc.mDurations.addDuration(mySrc.mActiveProcState, mySrc.mActiveDuration);
+ mySrc.mActiveDuration = 0;
+ mySrc.mActiveProcState = ProcessStats.STATE_NOTHING;
+ }
+ } else if (mySrc.mActiveDuration != 0) {
+ // Both have a single inline duration... we can either add them together,
+ // or need to expand to multiple durations.
+ if (mySrc.mActiveProcState == otherSrc.mActiveProcState) {
+ mySrc.mDuration += otherSrc.mDuration;
+ } else {
+ // The two have durations with different proc states, need to turn
+ // in to multiple durations.
+ mySrc.makeDurations();
+ mySrc.mDurations.addDuration(mySrc.mActiveProcState, mySrc.mActiveDuration);
+ mySrc.mDurations.addDuration(otherSrc.mActiveProcState,
+ otherSrc.mActiveDuration);
+ mySrc.mActiveDuration = 0;
+ mySrc.mActiveProcState = ProcessStats.STATE_NOTHING;
+ }
+ } else {
+ // The other one has a duration, and we know the target doesn't. Copy over.
+ mySrc.mActiveProcState = otherSrc.mActiveProcState;
+ mySrc.mActiveDuration = otherSrc.mActiveDuration;
+ }
+ }
}
}
@@ -275,7 +343,6 @@
}
public void resetSafely(long now) {
- mDurations.resetTable();
if (!isInUse()) {
mSources.clear();
} else {
@@ -293,6 +360,7 @@
src.mActiveCount = 0;
}
src.mActiveDuration = 0;
+ src.mDurations = null;
} else {
mSources.removeAt(isrc);
}
@@ -301,7 +369,6 @@
}
public void writeToParcel(ProcessStats stats, Parcel out, long nowUptime) {
- mDurations.writeToParcel(out);
final int NSRC = mSources.size();
out.writeInt(NSRC);
for (int isrc = 0; isrc < NSRC; isrc++) {
@@ -312,7 +379,14 @@
out.writeInt(src.mCount);
out.writeLong(src.mDuration);
out.writeInt(src.mActiveCount);
- out.writeLong(src.mActiveDuration);
+ if (src.mDurations != null) {
+ out.writeInt(1);
+ src.mDurations.writeToParcel(out);
+ } else {
+ out.writeInt(0);
+ out.writeInt(src.mActiveProcState);
+ out.writeLong(src.mActiveDuration);
+ }
}
}
@@ -321,9 +395,6 @@
* caused it to fail.
*/
public String readFromParcel(ProcessStats stats, Parcel in, int parcelVersion) {
- if (!mDurations.readFromParcel(in)) {
- return "Duration table corrupt";
- }
final int NSRC = in.readInt();
if (NSRC < 0 || NSRC > 100000) {
return "Association with bad src count: " + NSRC;
@@ -336,7 +407,15 @@
src.mCount = in.readInt();
src.mDuration = in.readLong();
src.mActiveCount = in.readInt();
- src.mActiveDuration = in.readLong();
+ if (in.readInt() != 0) {
+ src.makeDurations();
+ if (!src.mDurations.readFromParcel(in)) {
+ return "Duration table corrupt: " + key + " <- " + src;
+ }
+ } else {
+ src.mActiveProcState = in.readInt();
+ src.mActiveDuration = in.readLong();
+ }
mSources.put(key, src);
}
return null;
@@ -351,7 +430,12 @@
src.mStartUptime = nowUptime;
}
if (src.mActiveStartUptime > 0) {
- src.mActiveDuration += nowUptime - src.mActiveStartUptime;
+ final long duration = src.mActiveDuration + nowUptime - src.mActiveStartUptime;
+ if (src.mDurations != null) {
+ src.mDurations.addDuration(src.mActiveProcState, duration);
+ } else {
+ src.mActiveDuration = duration;
+ }
src.mActiveStartUptime = nowUptime;
}
}
@@ -359,7 +443,7 @@
}
public void dumpStats(PrintWriter pw, String prefix, String prefixInner, String headerPrefix,
- long now, long totalTime, boolean dumpSummary, boolean dumpAll) {
+ long now, long totalTime, boolean dumpDetails, boolean dumpAll) {
if (dumpAll) {
pw.print(prefix);
pw.print("mNumActive=");
@@ -376,18 +460,18 @@
UserHandle.formatUid(pw, key.mUid);
pw.println(":");
pw.print(prefixInner);
- pw.print(" Count ");
+ pw.print(" Total count ");
pw.print(src.mCount);
long duration = src.mDuration;
if (src.mNesting > 0) {
duration += now - src.mStartUptime;
}
if (dumpAll) {
- pw.print(" / Duration ");
+ pw.print(": Duration ");
TimeUtils.formatDuration(duration, pw);
pw.print(" / ");
} else {
- pw.print(" / time ");
+ pw.print(": time ");
}
DumpUtils.printPercent(pw, (double)duration/(double)totalTime);
if (src.mNesting > 0) {
@@ -401,30 +485,120 @@
pw.print(")");
}
pw.println();
- if (src.mActiveCount > 0) {
+ if (src.mActiveCount > 0 || src.mDurations != null || src.mActiveDuration != 0
+ || src.mActiveStartUptime != 0) {
pw.print(prefixInner);
pw.print(" Active count ");
pw.print(src.mActiveCount);
- duration = src.mActiveDuration;
- if (src.mActiveStartUptime > 0) {
- duration += now - src.mActiveStartUptime;
- }
- if (dumpAll) {
- pw.print(" / Duration ");
- TimeUtils.formatDuration(duration, pw);
- pw.print(" / ");
+ if (dumpDetails) {
+ if (dumpAll) {
+ pw.print(src.mDurations != null ? " (multi-field)" : " (inline)");
+ }
+ pw.println(":");
+ dumpTime(pw, prefixInner, src, totalTime, now, dumpDetails, dumpAll);
} else {
- pw.print(" / time ");
+ pw.print(": ");
+ dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll);
+ pw.println();
}
- DumpUtils.printPercent(pw, (double)duration/(double)totalTime);
- if (src.mActiveStartUptime > 0) {
- pw.print(" (running)");
+ }
+ if (dumpAll) {
+ if (src.mInTrackingList) {
+ pw.print(prefixInner);
+ pw.print(" mInTrackingList=");
+ pw.println(src.mInTrackingList);
}
- pw.println();
+ if (src.mProcState != ProcessStats.STATE_NOTHING) {
+ pw.print(prefixInner);
+ pw.print(" mProcState=");
+ pw.print(DumpUtils.STATE_NAMES[src.mProcState]);
+ pw.print(" mProcStateSeq=");
+ pw.println(src.mProcStateSeq);
+ }
}
}
}
+ void dumpActiveDurationSummary(PrintWriter pw, final SourceState src, long totalTime,
+ long now, boolean dumpAll) {
+ long duration = dumpTime(null, null, src, totalTime, now, false, false);
+ final boolean isRunning = duration < 0;
+ if (isRunning) {
+ duration = -duration;
+ }
+ if (dumpAll) {
+ pw.print("Duration ");
+ TimeUtils.formatDuration(duration, pw);
+ pw.print(" / ");
+ } else {
+ pw.print("time ");
+ }
+ DumpUtils.printPercent(pw, (double) duration / (double) totalTime);
+ if (src.mActiveStartUptime > 0) {
+ pw.print(" (running)");
+ }
+ pw.println();
+ }
+
+ long dumpTime(PrintWriter pw, String prefix, final SourceState src, long overallTime, long now,
+ boolean dumpDetails, boolean dumpAll) {
+ long totalTime = 0;
+ boolean isRunning = false;
+ for (int iprocstate = 0; iprocstate < ProcessStats.STATE_COUNT; iprocstate++) {
+ long time;
+ if (src.mDurations != null) {
+ time = src.mDurations.getValueForId((byte)iprocstate);
+ } else {
+ time = src.mActiveProcState == iprocstate ? src.mDuration : 0;
+ }
+ final String running;
+ if (src.mActiveStartUptime != 0 && src.mActiveProcState == iprocstate) {
+ running = " (running)";
+ isRunning = true;
+ time += now - src.mActiveStartUptime;
+ } else {
+ running = null;
+ }
+ if (time != 0) {
+ if (pw != null) {
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print(DumpUtils.STATE_LABELS[iprocstate]);
+ pw.print(": ");
+ if (dumpAll) {
+ pw.print("Duration ");
+ TimeUtils.formatDuration(time, pw);
+ pw.print(" / ");
+ } else {
+ pw.print("time ");
+ }
+ DumpUtils.printPercent(pw, (double) time / (double) overallTime);
+ if (running != null) {
+ pw.print(running);
+ }
+ pw.println();
+ }
+ totalTime += time;
+ }
+ }
+ if (totalTime != 0 && pw != null) {
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print(DumpUtils.STATE_LABEL_TOTAL);
+ pw.print(": ");
+ if (dumpAll) {
+ pw.print("Duration ");
+ TimeUtils.formatDuration(totalTime, pw);
+ pw.print(" / ");
+ } else {
+ pw.print("time ");
+ }
+ DumpUtils.printPercent(pw, (double) totalTime / (double) overallTime);
+ pw.println();
+ }
+ return isRunning ? -totalTime : totalTime;
+ }
+
public void dumpTimesCheckin(PrintWriter pw, String pkgName, int uid, long vers,
String associationName, long now) {
final int NSRC = mSources.size();
@@ -454,12 +628,30 @@
pw.print(duration);
pw.print(",");
pw.print(src.mActiveCount);
- duration = src.mActiveDuration;
- if (src.mActiveStartUptime > 0) {
- duration += now - src.mActiveStartUptime;
+ final long timeNow = src.mActiveStartUptime != 0 ? (now-src.mActiveStartUptime) : 0;
+ if (src.mDurations != null) {
+ final int N = src.mDurations.getKeyCount();
+ for (int i=0; i<N; i++) {
+ final int dkey = src.mDurations.getKeyAt(i);
+ duration = src.mDurations.getValue(dkey);
+ if (dkey == src.mActiveProcState) {
+ duration += timeNow;
+ }
+ final int procState = SparseMappingTable.getIdFromKey(dkey);
+ pw.print(",");
+ DumpUtils.printArrayEntry(pw, DumpUtils.STATE_TAGS, procState, 1);
+ pw.print(':');
+ pw.print(duration);
+ }
+ } else {
+ duration = src.mActiveDuration + timeNow;
+ if (duration != 0) {
+ pw.print(",");
+ DumpUtils.printArrayEntry(pw, DumpUtils.STATE_TAGS, src.mActiveProcState, 1);
+ pw.print(':');
+ pw.print(duration);
+ }
}
- pw.print(",");
- pw.print(duration);
pw.println();
}
}
diff --git a/core/java/com/android/internal/app/procstats/DumpUtils.java b/core/java/com/android/internal/app/procstats/DumpUtils.java
index 06b6552..e6073e5 100644
--- a/core/java/com/android/internal/app/procstats/DumpUtils.java
+++ b/core/java/com/android/internal/app/procstats/DumpUtils.java
@@ -48,6 +48,9 @@
*/
public final class DumpUtils {
public static final String[] STATE_NAMES;
+ public static final String[] STATE_LABELS;
+ public static final String STATE_LABEL_TOTAL;
+ public static final String STATE_LABEL_CACHED;
public static final String[] STATE_NAMES_CSV;
static final String[] STATE_TAGS;
static final int[] STATE_PROTO_ENUMS;
@@ -55,52 +58,70 @@
// Make the mapping easy to update.
static {
STATE_NAMES = new String[STATE_COUNT];
- STATE_NAMES[STATE_PERSISTENT] = "Persist";
- STATE_NAMES[STATE_TOP] = "Top";
- STATE_NAMES[STATE_IMPORTANT_FOREGROUND] = "ImpFg";
- STATE_NAMES[STATE_IMPORTANT_BACKGROUND] = "ImpBg";
- STATE_NAMES[STATE_BACKUP] = "Backup";
- STATE_NAMES[STATE_SERVICE] = "Service";
- STATE_NAMES[STATE_SERVICE_RESTARTING] = "ServRst";
- STATE_NAMES[STATE_RECEIVER] = "Receivr";
- STATE_NAMES[STATE_HEAVY_WEIGHT] = "HeavyWt";
- STATE_NAMES[STATE_HOME] = "Home";
- STATE_NAMES[STATE_LAST_ACTIVITY] = "LastAct";
- STATE_NAMES[STATE_CACHED_ACTIVITY] = "CchAct";
- STATE_NAMES[STATE_CACHED_ACTIVITY_CLIENT] = "CchCAct";
- STATE_NAMES[STATE_CACHED_EMPTY] = "CchEmty";
+ STATE_NAMES[STATE_PERSISTENT] = "Persist";
+ STATE_NAMES[STATE_TOP] = "Top";
+ STATE_NAMES[STATE_IMPORTANT_FOREGROUND] = "ImpFg";
+ STATE_NAMES[STATE_IMPORTANT_BACKGROUND] = "ImpBg";
+ STATE_NAMES[STATE_BACKUP] = "Backup";
+ STATE_NAMES[STATE_SERVICE] = "Service";
+ STATE_NAMES[STATE_SERVICE_RESTARTING] = "ServRst";
+ STATE_NAMES[STATE_RECEIVER] = "Receivr";
+ STATE_NAMES[STATE_HEAVY_WEIGHT] = "HeavyWt";
+ STATE_NAMES[STATE_HOME] = "Home";
+ STATE_NAMES[STATE_LAST_ACTIVITY] = "LastAct";
+ STATE_NAMES[STATE_CACHED_ACTIVITY] = "CchAct";
+ STATE_NAMES[STATE_CACHED_ACTIVITY_CLIENT] = "CchCAct";
+ STATE_NAMES[STATE_CACHED_EMPTY] = "CchEmty";
+
+ STATE_LABELS = new String[STATE_COUNT];
+ STATE_LABELS[STATE_PERSISTENT] = "Persistent";
+ STATE_LABELS[STATE_TOP] = " Top";
+ STATE_LABELS[STATE_IMPORTANT_FOREGROUND] = " Imp Fg";
+ STATE_LABELS[STATE_IMPORTANT_BACKGROUND] = " Imp Bg";
+ STATE_LABELS[STATE_BACKUP] = " Backup";
+ STATE_LABELS[STATE_SERVICE] = " Service";
+ STATE_LABELS[STATE_SERVICE_RESTARTING] = "Service Rs";
+ STATE_LABELS[STATE_RECEIVER] = " Receiver";
+ STATE_LABELS[STATE_HEAVY_WEIGHT] = " Heavy Wgt";
+ STATE_LABELS[STATE_HOME] = " (Home)";
+ STATE_LABELS[STATE_LAST_ACTIVITY] = "(Last Act)";
+ STATE_LABELS[STATE_CACHED_ACTIVITY] = " (Cch Act)";
+ STATE_LABELS[STATE_CACHED_ACTIVITY_CLIENT] = "(Cch CAct)";
+ STATE_LABELS[STATE_CACHED_EMPTY] = "(Cch Emty)";
+ STATE_LABEL_CACHED = " (Cached)";
+ STATE_LABEL_TOTAL = " TOTAL";
STATE_NAMES_CSV = new String[STATE_COUNT];
- STATE_NAMES_CSV[STATE_PERSISTENT] = "pers";
- STATE_NAMES_CSV[STATE_TOP] = "top";
- STATE_NAMES_CSV[STATE_IMPORTANT_FOREGROUND] = "impfg";
- STATE_NAMES_CSV[STATE_IMPORTANT_BACKGROUND] = "impbg";
- STATE_NAMES_CSV[STATE_BACKUP] = "backup";
- STATE_NAMES_CSV[STATE_SERVICE] = "service";
- STATE_NAMES_CSV[STATE_SERVICE_RESTARTING] = "service-rs";
- STATE_NAMES_CSV[STATE_RECEIVER] = "receiver";
- STATE_NAMES_CSV[STATE_HEAVY_WEIGHT] = "heavy";
- STATE_NAMES_CSV[STATE_HOME] = "home";
- STATE_NAMES_CSV[STATE_LAST_ACTIVITY] = "lastact";
- STATE_NAMES_CSV[STATE_CACHED_ACTIVITY] = "cch-activity";
- STATE_NAMES_CSV[STATE_CACHED_ACTIVITY_CLIENT] = "cch-aclient";
- STATE_NAMES_CSV[STATE_CACHED_EMPTY] = "cch-empty";
+ STATE_NAMES_CSV[STATE_PERSISTENT] = "pers";
+ STATE_NAMES_CSV[STATE_TOP] = "top";
+ STATE_NAMES_CSV[STATE_IMPORTANT_FOREGROUND] = "impfg";
+ STATE_NAMES_CSV[STATE_IMPORTANT_BACKGROUND] = "impbg";
+ STATE_NAMES_CSV[STATE_BACKUP] = "backup";
+ STATE_NAMES_CSV[STATE_SERVICE] = "service";
+ STATE_NAMES_CSV[STATE_SERVICE_RESTARTING] = "service-rs";
+ STATE_NAMES_CSV[STATE_RECEIVER] = "receiver";
+ STATE_NAMES_CSV[STATE_HEAVY_WEIGHT] = "heavy";
+ STATE_NAMES_CSV[STATE_HOME] = "home";
+ STATE_NAMES_CSV[STATE_LAST_ACTIVITY] = "lastact";
+ STATE_NAMES_CSV[STATE_CACHED_ACTIVITY] = "cch-activity";
+ STATE_NAMES_CSV[STATE_CACHED_ACTIVITY_CLIENT] = "cch-aclient";
+ STATE_NAMES_CSV[STATE_CACHED_EMPTY] = "cch-empty";
STATE_TAGS = new String[STATE_COUNT];
- STATE_TAGS[STATE_PERSISTENT] = "p";
- STATE_TAGS[STATE_TOP] = "t";
- STATE_TAGS[STATE_IMPORTANT_FOREGROUND] = "f";
- STATE_TAGS[STATE_IMPORTANT_BACKGROUND] = "b";
- STATE_TAGS[STATE_BACKUP] = "u";
- STATE_TAGS[STATE_SERVICE] = "s";
- STATE_TAGS[STATE_SERVICE_RESTARTING] = "x";
- STATE_TAGS[STATE_RECEIVER] = "r";
- STATE_TAGS[STATE_HEAVY_WEIGHT] = "w";
- STATE_TAGS[STATE_HOME] = "h";
- STATE_TAGS[STATE_LAST_ACTIVITY] = "l";
- STATE_TAGS[STATE_CACHED_ACTIVITY] = "a";
- STATE_TAGS[STATE_CACHED_ACTIVITY_CLIENT] = "c";
- STATE_TAGS[STATE_CACHED_EMPTY] = "e";
+ STATE_TAGS[STATE_PERSISTENT] = "p";
+ STATE_TAGS[STATE_TOP] = "t";
+ STATE_TAGS[STATE_IMPORTANT_FOREGROUND] = "f";
+ STATE_TAGS[STATE_IMPORTANT_BACKGROUND] = "b";
+ STATE_TAGS[STATE_BACKUP] = "u";
+ STATE_TAGS[STATE_SERVICE] = "s";
+ STATE_TAGS[STATE_SERVICE_RESTARTING] = "x";
+ STATE_TAGS[STATE_RECEIVER] = "r";
+ STATE_TAGS[STATE_HEAVY_WEIGHT] = "w";
+ STATE_TAGS[STATE_HOME] = "h";
+ STATE_TAGS[STATE_LAST_ACTIVITY] = "l";
+ STATE_TAGS[STATE_CACHED_ACTIVITY] = "a";
+ STATE_TAGS[STATE_CACHED_ACTIVITY_CLIENT] = "c";
+ STATE_TAGS[STATE_CACHED_EMPTY] = "e";
STATE_PROTO_ENUMS = new int[STATE_COUNT];
STATE_PROTO_ENUMS[STATE_PERSISTENT] = ProcessStatsProto.State.PERSISTENT;
@@ -166,7 +187,7 @@
pw.print("SOff/");
break;
case ADJ_SCREEN_ON:
- pw.print("SOn /");
+ pw.print(" SOn/");
break;
default:
pw.print("????/");
@@ -201,11 +222,11 @@
if (sep != 0) pw.print(sep);
break;
case ADJ_MEM_FACTOR_MODERATE:
- pw.print("Mod ");
+ pw.print(" Mod");
if (sep != 0) pw.print(sep);
break;
case ADJ_MEM_FACTOR_LOW:
- pw.print("Low ");
+ pw.print(" Low");
if (sep != 0) pw.print(sep);
break;
case ADJ_MEM_FACTOR_CRITICAL:
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index ad42288..943c8bd 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -25,6 +25,7 @@
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Slog;
+import android.util.SparseLongArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoUtils;
@@ -62,8 +63,6 @@
import java.io.PrintWriter;
import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
public final class ProcessState {
private static final String TAG = "ProcessStats";
@@ -127,6 +126,7 @@
private final long mVersion;
private final DurationsTable mDurations;
private final PssTable mPssTable;
+ private final long[] mTotalRunningPss = new long[ProcessStats.PSS_COUNT];
private ProcessState mCommonProcess;
private int mCurCombinedState = STATE_NOTHING;
@@ -135,6 +135,9 @@
private int mLastPssState = STATE_NOTHING;
private long mLastPssTime;
+ private long mTotalRunningStartTime;
+ private long mTotalRunningDuration;
+
private boolean mActive;
private int mNumActiveServices;
private int mNumStartedServices;
@@ -182,6 +185,9 @@
mVersion = vers;
mCurCombinedState = commonProcess.mCurCombinedState;
mStartTime = now;
+ if (mCurCombinedState != STATE_NOTHING) {
+ mTotalRunningStartTime = now;
+ }
mDurations = new DurationsTable(commonProcess.mStats.mTableData);
mPssTable = new PssTable(commonProcess.mStats.mTableData);
}
@@ -190,6 +196,8 @@
ProcessState pnew = new ProcessState(this, mPackage, mUid, mVersion, mName, now);
pnew.mDurations.addDurations(mDurations);
pnew.mPssTable.copyFrom(mPssTable, PSS_COUNT);
+ System.arraycopy(mTotalRunningPss, 0, pnew.mTotalRunningPss, 0, ProcessStats.PSS_COUNT);
+ pnew.mTotalRunningDuration = getTotalRunningDuration(now);
pnew.mNumExcessiveCpu = mNumExcessiveCpu;
pnew.mNumCachedKill = mNumCachedKill;
pnew.mMinCachedKillPss = mMinCachedKillPss;
@@ -235,7 +243,7 @@
public void setMultiPackage(boolean val) {
mMultiPackage = val;
}
-
+
public int getDurationsBucketCount() {
return mDurations.getKeyCount();
}
@@ -243,6 +251,10 @@
public void add(ProcessState other) {
mDurations.addDurations(other.mDurations);
mPssTable.mergeStats(other.mPssTable);
+ // Note that we don't touch mTotalRunningPss, because in current use
+ // 'other' is older stats that are being added in to these newer ones.
+ // So the newer ones keep track of the total running time, which is always
+ // the right thing over whatever was in older stats.
mNumExcessiveCpu += other.mNumExcessiveCpu;
if (other.mNumCachedKill > 0) {
addCachedKill(other.mNumCachedKill, other.mMinCachedKillPss,
@@ -277,6 +289,10 @@
out.writeInt(mMultiPackage ? 1 : 0);
mDurations.writeToParcel(out);
mPssTable.writeToParcel(out);
+ for (int i = 0; i < ProcessStats.PSS_COUNT; i++) {
+ out.writeLong(mTotalRunningPss[i]);
+ }
+ out.writeLong(getTotalRunningDuration(now));
out.writeInt(0); // was mNumExcessiveWake
out.writeInt(mNumExcessiveCpu);
out.writeInt(mNumCachedKill);
@@ -300,6 +316,10 @@
if (!mPssTable.readFromParcel(in)) {
return false;
}
+ for (int i = 0; i < ProcessStats.PSS_COUNT; i++) {
+ mTotalRunningPss[i] = in.readLong();
+ }
+ mTotalRunningDuration = in.readLong();
in.readInt(); // was mNumExcessiveWake
mNumExcessiveCpu = in.readInt();
mNumCachedKill = in.readInt();
@@ -334,7 +354,8 @@
public boolean hasAnyData() {
return !(mDurations.getKeyCount() == 0
&& mCurCombinedState == STATE_NOTHING
- && mPssTable.getKeyCount() == 0);
+ && mPssTable.getKeyCount() == 0
+ && mTotalRunningPss[PSS_SAMPLE_COUNT] == 0);
}
/**
@@ -374,6 +395,19 @@
if (!mDead && (mCurCombinedState != state)) {
//Slog.i(TAG, "Setting state in " + mName + "/" + mPackage + ": " + state);
commitStateTime(now);
+ if (state == STATE_NOTHING) {
+ // We are transitioning to a no longer running state... stop counting run time.
+ mTotalRunningDuration += now - mTotalRunningStartTime;
+ mTotalRunningStartTime = 0;
+ } else if (mCurCombinedState == STATE_NOTHING) {
+ // We previously weren't running... now starting again, clear out total
+ // running info.
+ mTotalRunningDuration = 0;
+ mTotalRunningStartTime = now;
+ for (int i = ProcessStats.PSS_COUNT - 1; i >= 0; i--) {
+ mTotalRunningPss[i] = 0;
+ }
+ }
mCurCombinedState = state;
}
}
@@ -388,6 +422,8 @@
if (dur > 0) {
mDurations.addDuration(mCurCombinedState, dur);
}
+ mTotalRunningDuration += now - mTotalRunningStartTime;
+ mTotalRunningStartTime = now;
}
mStartTime = now;
}
@@ -496,6 +532,8 @@
// First update the common process.
mCommonProcess.mPssTable.mergeStats(mCurCombinedState, 1, pss, pss, pss, uss, uss, uss,
rss, rss, rss);
+ PssTable.mergeStats(mCommonProcess.mTotalRunningPss, 0, 1, pss, pss, pss, uss, uss, uss,
+ rss, rss, rss);
// If the common process is not multi-package, there is nothing else to do.
if (!mCommonProcess.mMultiPackage) {
@@ -504,7 +542,10 @@
if (pkgList != null) {
for (int ip=pkgList.size()-1; ip>=0; ip--) {
- pullFixedProc(pkgList, ip).mPssTable.mergeStats(mCurCombinedState, 1,
+ ProcessState fixedProc = pullFixedProc(pkgList, ip);
+ fixedProc.mPssTable.mergeStats(mCurCombinedState, 1,
+ pss, pss, pss, uss, uss, uss, rss, rss, rss);
+ PssTable.mergeStats(fixedProc.mTotalRunningPss, 0, 1,
pss, pss, pss, uss, uss, uss, rss, rss, rss);
}
}
@@ -621,6 +662,11 @@
return proc;
}
+ public long getTotalRunningDuration(long now) {
+ return mTotalRunningDuration +
+ (mTotalRunningStartTime != 0 ? (now - mTotalRunningStartTime) : 0);
+ }
+
public long getDuration(int state, long now) {
long time = mDurations.getValueForId((byte)state);
if (mCurCombinedState == state) {
@@ -671,7 +717,7 @@
/**
* Sums up the PSS data and adds it to 'data'.
- *
+ *
* @param data The aggregate data is added here.
* @param now SystemClock.uptimeMillis()
*/
@@ -787,35 +833,36 @@
pw.print(" / v");
pw.print(mVersion);
pw.println(":");
- dumpProcessSummaryDetails(pw, prefix, " TOTAL: ", screenStates, memStates,
- procStates, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Persistent: ", screenStates, memStates,
- new int[] { STATE_PERSISTENT }, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Top: ", screenStates, memStates,
- new int[] {STATE_TOP}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Imp Fg: ", screenStates, memStates,
- new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Imp Bg: ", screenStates, memStates,
- new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Backup: ", screenStates, memStates,
- new int[] {STATE_BACKUP}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Heavy Wgt: ", screenStates, memStates,
- new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Service: ", screenStates, memStates,
- new int[] {STATE_SERVICE}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Service Rs: ", screenStates, memStates,
- new int[] {STATE_SERVICE_RESTARTING}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Receiver: ", screenStates, memStates,
- new int[] {STATE_RECEIVER}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " Heavy: ", screenStates, memStates,
- new int[] {STATE_HOME}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " (Home): ", screenStates, memStates,
- new int[] {STATE_HOME}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " (Last Act): ", screenStates, memStates,
- new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true);
- dumpProcessSummaryDetails(pw, prefix, " (Cached): ", screenStates, memStates,
- new int[] {STATE_CACHED_ACTIVITY, STATE_CACHED_ACTIVITY_CLIENT,
- STATE_CACHED_EMPTY}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABEL_TOTAL,
+ screenStates, memStates, procStates, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_PERSISTENT],
+ screenStates, memStates, new int[] { STATE_PERSISTENT }, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_TOP],
+ screenStates, memStates, new int[] {STATE_TOP}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_IMPORTANT_FOREGROUND],
+ screenStates, memStates, new int[] { STATE_IMPORTANT_FOREGROUND }, now, totalTime,
+ true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_IMPORTANT_BACKGROUND],
+ screenStates, memStates, new int[] {STATE_IMPORTANT_BACKGROUND}, now, totalTime,
+ true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_BACKUP],
+ screenStates, memStates, new int[] {STATE_BACKUP}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_SERVICE],
+ screenStates, memStates, new int[] {STATE_SERVICE}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_SERVICE_RESTARTING],
+ screenStates, memStates, new int[] {STATE_SERVICE_RESTARTING}, now, totalTime,
+ true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_RECEIVER],
+ screenStates, memStates, new int[] {STATE_RECEIVER}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_HEAVY_WEIGHT],
+ screenStates, memStates, new int[] {STATE_HEAVY_WEIGHT}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_HOME],
+ screenStates, memStates, new int[] {STATE_HOME}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABELS[STATE_LAST_ACTIVITY],
+ screenStates, memStates, new int[] {STATE_LAST_ACTIVITY}, now, totalTime, true);
+ dumpProcessSummaryDetails(pw, prefix, DumpUtils.STATE_LABEL_CACHED,
+ screenStates, memStates, new int[] {STATE_CACHED_ACTIVITY,
+ STATE_CACHED_ACTIVITY_CLIENT, STATE_CACHED_EMPTY}, now, totalTime, true);
}
public void dumpProcessState(PrintWriter pw, String prefix,
@@ -833,6 +880,7 @@
String running = "";
if (mCurCombinedState == bucket) {
running = " (running)";
+ time += now - mStartTime;
}
if (time != 0) {
pw.print(prefix);
@@ -846,7 +894,7 @@
printedMem != imem ? imem : STATE_NOTHING, '/');
printedMem = imem;
}
- pw.print(DumpUtils.STATE_NAMES[procStates[ip]]); pw.print(": ");
+ pw.print(DumpUtils.STATE_LABELS[procStates[ip]]); pw.print(": ");
TimeUtils.formatDuration(time, pw); pw.println(running);
totalTime += time;
}
@@ -861,14 +909,15 @@
if (memStates.length > 1) {
DumpUtils.printMemLabel(pw, STATE_NOTHING, '/');
}
- pw.print("TOTAL : ");
+ pw.print(DumpUtils.STATE_LABEL_TOTAL);
+ pw.print(": ");
TimeUtils.formatDuration(totalTime, pw);
pw.println();
}
}
public void dumpPss(PrintWriter pw, String prefix,
- int[] screenStates, int[] memStates, int[] procStates) {
+ int[] screenStates, int[] memStates, int[] procStates, long now) {
boolean printedHeader = false;
int printedScreen = -1;
for (int is=0; is<screenStates.length; is++) {
@@ -878,52 +927,51 @@
final int iscreen = screenStates[is];
final int imem = memStates[im];
final int bucket = ((iscreen + imem) * STATE_COUNT) + procStates[ip];
- long count = getPssSampleCount(bucket);
- if (count > 0) {
- if (!printedHeader) {
- pw.print(prefix);
- pw.print("PSS/USS (");
- pw.print(mPssTable.getKeyCount());
- pw.println(" entries):");
- printedHeader = true;
- }
- pw.print(prefix);
- pw.print(" ");
- if (screenStates.length > 1) {
- DumpUtils.printScreenLabel(pw,
- printedScreen != iscreen ? iscreen : STATE_NOTHING);
- printedScreen = iscreen;
- }
- if (memStates.length > 1) {
- DumpUtils.printMemLabel(pw,
- printedMem != imem ? imem : STATE_NOTHING, '/');
- printedMem = imem;
- }
- pw.print(DumpUtils.STATE_NAMES[procStates[ip]]); pw.print(": ");
- pw.print(count);
- pw.print(" samples ");
- DebugUtils.printSizeValue(pw, getPssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssMaximum(bucket) * 1024);
- pw.print(" / ");
- DebugUtils.printSizeValue(pw, getPssUssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssUssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssUssMaximum(bucket) * 1024);
- pw.print(" / ");
- DebugUtils.printSizeValue(pw, getPssRssMinimum(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssRssAverage(bucket) * 1024);
- pw.print(" ");
- DebugUtils.printSizeValue(pw, getPssRssMaximum(bucket) * 1024);
- pw.println();
+ final int key = mPssTable.getKey((byte)bucket);
+ if (key == SparseMappingTable.INVALID_KEY) {
+ continue;
}
+ final long[] table = mPssTable.getArrayForKey(key);
+ final int tableOffset = SparseMappingTable.getIndexFromKey(key);
+ if (!printedHeader) {
+ pw.print(prefix);
+ pw.print("PSS/USS (");
+ pw.print(mPssTable.getKeyCount());
+ pw.println(" entries):");
+ printedHeader = true;
+ }
+ pw.print(prefix);
+ pw.print(" ");
+ if (screenStates.length > 1) {
+ DumpUtils.printScreenLabel(pw,
+ printedScreen != iscreen ? iscreen : STATE_NOTHING);
+ printedScreen = iscreen;
+ }
+ if (memStates.length > 1) {
+ DumpUtils.printMemLabel(pw,
+ printedMem != imem ? imem : STATE_NOTHING, '/');
+ printedMem = imem;
+ }
+ pw.print(DumpUtils.STATE_LABELS[procStates[ip]]); pw.print(": ");
+ dumpPssSamples(pw, table, tableOffset);
+ pw.println();
}
}
}
+ final long totalRunningDuration = getTotalRunningDuration(now);
+ if (totalRunningDuration != 0) {
+ pw.print(prefix);
+ pw.print("Cur time ");
+ TimeUtils.formatDuration(totalRunningDuration, pw);
+ if (mTotalRunningStartTime != 0) {
+ pw.print(" (running)");
+ }
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ pw.print(": ");
+ dumpPssSamples(pw, mTotalRunningPss, 0);
+ }
+ pw.println();
+ }
if (mNumExcessiveCpu != 0) {
pw.print(prefix); pw.print("Killed for excessive CPU use: ");
pw.print(mNumExcessiveCpu); pw.println(" times");
@@ -937,6 +985,28 @@
}
}
+ public static void dumpPssSamples(PrintWriter pw, long[] table, int offset) {
+ DebugUtils.printSizeValue(pw, table[offset + PSS_MINIMUM] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_AVERAGE] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_MAXIMUM] * 1024);
+ pw.print("/");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_USS_MINIMUM] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_USS_AVERAGE] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_USS_MAXIMUM] * 1024);
+ pw.print("/");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_RSS_MINIMUM] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_RSS_AVERAGE] * 1024);
+ pw.print("-");
+ DebugUtils.printSizeValue(pw, table[offset + PSS_RSS_MAXIMUM] * 1024);
+ pw.print(" over ");
+ pw.print(table[offset + PSS_SAMPLE_COUNT]);
+ }
+
private void dumpProcessSummaryDetails(PrintWriter pw, String prefix,
String label, int[] screenStates, int[] memStates, int[] procStates,
long now, long totalTime, boolean full) {
@@ -950,7 +1020,9 @@
pw.print(prefix);
}
if (label != null) {
+ pw.print(" ");
pw.print(label);
+ pw.print(": ");
}
totals.print(pw, totalTime, full);
if (prefix != null) {
@@ -1112,6 +1184,21 @@
dumpAllPssCheckin(pw);
pw.println();
}
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ pw.print("pkgrun,");
+ pw.print(pkgName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(vers);
+ pw.print(",");
+ pw.print(DumpUtils.collapseString(pkgName, itemName));
+ pw.print(",");
+ pw.print(getTotalRunningDuration(now));
+ pw.print(",");
+ dumpPssSamplesCheckin(pw, mTotalRunningPss, 0);
+ pw.println();
+ }
if (mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
pw.print("pkgkills,");
pw.print(pkgName);
@@ -1154,6 +1241,17 @@
dumpAllPssCheckin(pw);
pw.println();
}
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ pw.print("procrun,");
+ pw.print(procName);
+ pw.print(",");
+ pw.print(uid);
+ pw.print(",");
+ pw.print(getTotalRunningDuration(now));
+ pw.print(",");
+ dumpPssSamplesCheckin(pw, mTotalRunningPss, 0);
+ pw.println();
+ }
if (mNumExcessiveCpu > 0 || mNumCachedKill > 0) {
pw.print("kills,");
pw.print(procName);
@@ -1200,28 +1298,33 @@
pw.print(',');
DumpUtils.printProcStateTag(pw, type);
pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_SAMPLE_COUNT));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_MINIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_AVERAGE));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_MAXIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_USS_MINIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_USS_AVERAGE));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_USS_MAXIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_RSS_MINIMUM));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_RSS_AVERAGE));
- pw.print(':');
- pw.print(mPssTable.getValue(key, PSS_RSS_MAXIMUM));
+ dumpPssSamplesCheckin(pw, mPssTable.getArrayForKey(key),
+ SparseMappingTable.getIndexFromKey(key));
}
}
+ public static void dumpPssSamplesCheckin(PrintWriter pw, long[] table, int offset) {
+ pw.print(table[offset + PSS_SAMPLE_COUNT]);
+ pw.print(':');
+ pw.print(table[offset + PSS_MINIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_AVERAGE]);
+ pw.print(':');
+ pw.print(table[offset + PSS_MAXIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_USS_MINIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_USS_AVERAGE]);
+ pw.print(':');
+ pw.print(table[offset + PSS_USS_MAXIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_RSS_MINIMUM]);
+ pw.print(':');
+ pw.print(table[offset + PSS_RSS_AVERAGE]);
+ pw.print(':');
+ pw.print(table[offset + PSS_RSS_MAXIMUM]);
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder(128);
@@ -1249,7 +1352,7 @@
}
// Group proc stats by type (screen state + mem state + process state)
- Map<Integer, Long> durationByState = new HashMap<>();
+ SparseLongArray durationByState = new SparseLongArray();
boolean didCurState = false;
for (int i=0; i<mDurations.getKeyCount(); i++) {
final int key = mDurations.getKeyAt(i);
@@ -1268,7 +1371,7 @@
for (int i=0; i<mPssTable.getKeyCount(); i++) {
final int key = mPssTable.getKeyAt(i);
final int type = SparseMappingTable.getIdFromKey(key);
- if (!durationByState.containsKey(type)) {
+ if (durationByState.indexOfKey(type) < 0) {
// state without duration should not have stats!
continue;
}
@@ -1280,36 +1383,35 @@
type);
long duration = durationByState.get(type);
- durationByState.remove(type); // remove the key since it is already being dumped.
+ durationByState.delete(type); // remove the key since it is already being dumped.
proto.write(ProcessStatsProto.State.DURATION_MS, duration);
- proto.write(ProcessStatsProto.State.SAMPLE_SIZE, mPssTable.getValue(key, PSS_SAMPLE_COUNT));
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.PSS,
- mPssTable.getValue(key, PSS_MINIMUM),
- mPssTable.getValue(key, PSS_AVERAGE),
- mPssTable.getValue(key, PSS_MAXIMUM));
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.USS,
- mPssTable.getValue(key, PSS_USS_MINIMUM),
- mPssTable.getValue(key, PSS_USS_AVERAGE),
- mPssTable.getValue(key, PSS_USS_MAXIMUM));
- ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.RSS,
- mPssTable.getValue(key, PSS_RSS_MINIMUM),
- mPssTable.getValue(key, PSS_RSS_AVERAGE),
- mPssTable.getValue(key, PSS_RSS_MAXIMUM));
+ mPssTable.writeStatsToProtoForKey(proto, key);
proto.end(stateToken);
}
- for (Map.Entry<Integer, Long> entry : durationByState.entrySet()) {
+ for (int i = 0; i < durationByState.size(); i++) {
final long stateToken = proto.start(ProcessStatsProto.STATES);
DumpUtils.printProcStateTagProto(proto,
ProcessStatsProto.State.SCREEN_STATE,
ProcessStatsProto.State.MEMORY_STATE,
ProcessStatsProto.State.PROCESS_STATE,
- entry.getKey());
- proto.write(ProcessStatsProto.State.DURATION_MS, entry.getValue());
+ durationByState.keyAt(i));
+ proto.write(ProcessStatsProto.State.DURATION_MS, durationByState.valueAt(i));
proto.end(stateToken);
}
+
+ final long totalRunningDuration = getTotalRunningDuration(now);
+ if (totalRunningDuration > 0) {
+ final long stateToken = proto.start(ProcessStatsProto.TOTAL_RUNNING_STATE);
+ proto.write(ProcessStatsProto.State.DURATION_MS, totalRunningDuration);
+ if (mTotalRunningPss[PSS_SAMPLE_COUNT] != 0) {
+ PssTable.writeStatsToProto(proto, mTotalRunningPss, 0);
+ }
+ proto.end(stateToken);
+ }
+
proto.end(token);
}
}
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index 15f140e..d088354 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -158,7 +158,7 @@
};
// Current version of the parcel format.
- private static final int PARCEL_VERSION = 32;
+ private static final int PARCEL_VERSION = 34;
// In-memory Parcel magic number, used to detect attempts to unmarshall bad data
private static final int MAGIC = 0x50535454;
@@ -1380,9 +1380,13 @@
final int NUM = mTrackingAssociations.size();
for (int i = NUM - 1; i >= 0; i--) {
final AssociationState.SourceState act = mTrackingAssociations.get(i);
- if (act.mProcStateSeq != curSeq) {
+ if (act.mProcStateSeq != curSeq || act.mProcState >= ProcessStats.STATE_HOME) {
+ // If this association did not get touched the last time we computed
+ // process states, or its state ended up down in cached, then we no
+ // longer have a reason to track it at all.
+ act.stopActive(now);
act.mInTrackingList = false;
- act.mProcState = STATE_NOTHING;
+ act.mProcState = ProcessStats.STATE_NOTHING;
mTrackingAssociations.remove(i);
} else {
final ProcessState proc = act.getAssociationState().getProcess();
@@ -1407,7 +1411,7 @@
}
public void dumpLocked(PrintWriter pw, String reqPackage, long now, boolean dumpSummary,
- boolean dumpAll, boolean activeOnly) {
+ boolean dumpDetails, boolean dumpAll, boolean activeOnly) {
long totalTime = DumpUtils.dumpSingleTime(null, null, mMemFactorDurations, mMemFactor,
mStartTime, now);
boolean sepNeeded = false;
@@ -1479,7 +1483,7 @@
proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
ALL_PROC_STATES, now);
proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
- ALL_PROC_STATES);
+ ALL_PROC_STATES, now);
proc.dumpInternalLocked(pw, " ", dumpAll);
}
} else {
@@ -1538,7 +1542,7 @@
pw.println(":");
pw.print(" Process: "); pw.println(asc.getProcessName());
asc.dumpStats(pw, " ", " ", " ",
- now, totalTime, dumpSummary, dumpAll);
+ now, totalTime, dumpDetails, dumpAll);
}
}
}
@@ -1554,7 +1558,7 @@
int uid = uids.keyAt(iu);
numTotalProcs++;
final ProcessState proc = uids.valueAt(iu);
- if (proc.hasAnyData()) {
+ if (!proc.hasAnyData()) {
continue;
}
if (!proc.isMultiPackage()) {
@@ -1583,7 +1587,7 @@
pw.print(" entries)"); pw.println(":");
proc.dumpProcessState(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ,
ALL_PROC_STATES, now);
- proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES);
+ proc.dumpPss(pw, " ", ALL_SCREEN_ADJ, ALL_MEM_ADJ, ALL_PROC_STATES, now);
proc.dumpInternalLocked(pw, " ", dumpAll);
}
}
@@ -1632,21 +1636,8 @@
if (src.mActiveCount > 0) {
pw.print(" Active count ");
pw.print(src.mActiveCount);
- long duration = src.mActiveDuration;
- if (src.mActiveStartUptime > 0) {
- duration += now - src.mActiveStartUptime;
- }
- if (dumpAll) {
- pw.print(" / Duration ");
- TimeUtils.formatDuration(duration, pw);
- pw.print(" / ");
- } else {
- pw.print(" / time ");
- }
- DumpUtils.printPercent(pw, (double)duration/(double)totalTime);
- if (src.mActiveStartUptime > 0) {
- pw.print(" (running)");
- }
+ pw.print(": ");
+ asc.dumpActiveDurationSummary(pw, src, totalTime, now, dumpAll);
pw.println();
}
}
diff --git a/core/java/com/android/internal/app/procstats/PssTable.java b/core/java/com/android/internal/app/procstats/PssTable.java
index 1e7c566..f858e55 100644
--- a/core/java/com/android/internal/app/procstats/PssTable.java
+++ b/core/java/com/android/internal/app/procstats/PssTable.java
@@ -28,6 +28,10 @@
import static com.android.internal.app.procstats.ProcessStats.PSS_USS_MAXIMUM;
import static com.android.internal.app.procstats.ProcessStats.PSS_COUNT;
+import android.service.procstats.ProcessStatsProto;
+import android.util.proto.ProtoOutputStream;
+import android.util.proto.ProtoUtils;
+
/**
* Class to accumulate PSS data.
*/
@@ -46,18 +50,17 @@
public void mergeStats(PssTable that) {
final int N = that.getKeyCount();
for (int i=0; i<N; i++) {
- final int key = that.getKeyAt(i);
- final int state = SparseMappingTable.getIdFromKey(key);
- mergeStats(state, (int)that.getValue(key, PSS_SAMPLE_COUNT),
- that.getValue(key, PSS_MINIMUM),
- that.getValue(key, PSS_AVERAGE),
- that.getValue(key, PSS_MAXIMUM),
- that.getValue(key, PSS_USS_MINIMUM),
- that.getValue(key, PSS_USS_AVERAGE),
- that.getValue(key, PSS_USS_MAXIMUM),
- that.getValue(key, PSS_RSS_MINIMUM),
- that.getValue(key, PSS_RSS_AVERAGE),
- that.getValue(key, PSS_RSS_MAXIMUM));
+ final int thatKey = that.getKeyAt(i);
+ final int state = SparseMappingTable.getIdFromKey(thatKey);
+
+ final int key = getOrAddKey((byte)state, PSS_COUNT);
+ final long[] stats = getArrayForKey(key);
+ final int statsIndex = SparseMappingTable.getIndexFromKey(key);
+
+ final long[] thatStats = that.getArrayForKey(thatKey);
+ final int thatStatsIndex = SparseMappingTable.getIndexFromKey(thatKey);
+
+ mergeStats(stats, statsIndex, thatStats, thatStatsIndex);
}
}
@@ -68,64 +71,100 @@
public void mergeStats(int state, int inCount, long minPss, long avgPss, long maxPss,
long minUss, long avgUss, long maxUss, long minRss, long avgRss, long maxRss) {
final int key = getOrAddKey((byte)state, PSS_COUNT);
- final long count = getValue(key, PSS_SAMPLE_COUNT);
+ final long[] stats = getArrayForKey(key);
+ final int statsIndex = SparseMappingTable.getIndexFromKey(key);
+ mergeStats(stats, statsIndex, inCount, minPss, avgPss, maxPss, minUss, avgUss, maxUss,
+ minRss, avgRss, maxRss);
+ }
+
+ public static void mergeStats(final long[] stats, final int statsIndex,
+ final long[] thatStats, int thatStatsIndex) {
+ mergeStats(stats, statsIndex, (int)thatStats[thatStatsIndex + PSS_SAMPLE_COUNT],
+ thatStats[thatStatsIndex + PSS_MINIMUM],
+ thatStats[thatStatsIndex + PSS_AVERAGE],
+ thatStats[thatStatsIndex + PSS_MAXIMUM],
+ thatStats[thatStatsIndex + PSS_USS_MINIMUM],
+ thatStats[thatStatsIndex + PSS_USS_AVERAGE],
+ thatStats[thatStatsIndex + PSS_USS_MAXIMUM],
+ thatStats[thatStatsIndex + PSS_RSS_MINIMUM],
+ thatStats[thatStatsIndex + PSS_RSS_AVERAGE],
+ thatStats[thatStatsIndex + PSS_RSS_MAXIMUM]);
+ }
+
+ public static void mergeStats(final long[] stats, final int statsIndex, final int inCount,
+ final long minPss, final long avgPss, final long maxPss,
+ final long minUss, final long avgUss, final long maxUss,
+ final long minRss, final long avgRss, final long maxRss) {
+ final long count = stats[statsIndex + PSS_SAMPLE_COUNT];
if (count == 0) {
- setValue(key, PSS_SAMPLE_COUNT, inCount);
- setValue(key, PSS_MINIMUM, minPss);
- setValue(key, PSS_AVERAGE, avgPss);
- setValue(key, PSS_MAXIMUM, maxPss);
- setValue(key, PSS_USS_MINIMUM, minUss);
- setValue(key, PSS_USS_AVERAGE, avgUss);
- setValue(key, PSS_USS_MAXIMUM, maxUss);
- setValue(key, PSS_RSS_MINIMUM, minRss);
- setValue(key, PSS_RSS_AVERAGE, avgRss);
- setValue(key, PSS_RSS_MAXIMUM, maxRss);
+ stats[statsIndex + PSS_SAMPLE_COUNT] = inCount;
+ stats[statsIndex + PSS_MINIMUM] = minPss;
+ stats[statsIndex + PSS_AVERAGE] = avgPss;
+ stats[statsIndex + PSS_MAXIMUM] = maxPss;
+ stats[statsIndex + PSS_USS_MINIMUM] = minUss;
+ stats[statsIndex + PSS_USS_AVERAGE] = avgUss;
+ stats[statsIndex + PSS_USS_MAXIMUM] = maxUss;
+ stats[statsIndex + PSS_RSS_MINIMUM] = minRss;
+ stats[statsIndex + PSS_RSS_AVERAGE] = avgRss;
+ stats[statsIndex + PSS_RSS_MAXIMUM] = maxRss;
} else {
- setValue(key, PSS_SAMPLE_COUNT, count + inCount);
+ stats[statsIndex + PSS_SAMPLE_COUNT] = count + inCount;
- long val;
-
- val = getValue(key, PSS_MINIMUM);
- if (val > minPss) {
- setValue(key, PSS_MINIMUM, minPss);
+ if (stats[statsIndex + PSS_MINIMUM] > minPss) {
+ stats[statsIndex + PSS_MINIMUM] = minPss;
}
- val = getValue(key, PSS_AVERAGE);
- setValue(key, PSS_AVERAGE,
- (long)(((val*(double)count)+(avgPss*(double)inCount)) / (count+inCount)));
+ stats[statsIndex + PSS_AVERAGE] = (long)(((stats[statsIndex + PSS_AVERAGE]
+ * (double)count) + (avgPss * (double)inCount)) / (count + inCount));
- val = getValue(key, PSS_MAXIMUM);
- if (val < maxPss) {
- setValue(key, PSS_MAXIMUM, maxPss);
+ if (stats[statsIndex + PSS_MAXIMUM] < maxPss) {
+ stats[statsIndex + PSS_MAXIMUM] = maxPss;
}
- val = getValue(key, PSS_USS_MINIMUM);
- if (val > minUss) {
- setValue(key, PSS_USS_MINIMUM, minUss);
+ if (stats[statsIndex + PSS_USS_MINIMUM] > minUss) {
+ stats[statsIndex + PSS_USS_MINIMUM] = minUss;
}
- val = getValue(key, PSS_USS_AVERAGE);
- setValue(key, PSS_USS_AVERAGE,
- (long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount)));
+ stats[statsIndex + PSS_USS_AVERAGE] = (long)(((stats[statsIndex + PSS_USS_AVERAGE]
+ * (double)count) + (avgUss * (double)inCount)) / (count + inCount));
- val = getValue(key, PSS_USS_MAXIMUM);
- if (val < maxUss) {
- setValue(key, PSS_USS_MAXIMUM, maxUss);
+ if (stats[statsIndex + PSS_USS_MAXIMUM] < maxUss) {
+ stats[statsIndex + PSS_USS_MAXIMUM] = maxUss;
}
- val = getValue(key, PSS_RSS_MINIMUM);
- if (val > minUss) {
- setValue(key, PSS_RSS_MINIMUM, minUss);
+ if (stats[statsIndex + PSS_RSS_MINIMUM] > minRss) {
+ stats[statsIndex + PSS_RSS_MINIMUM] = minRss;
}
- val = getValue(key, PSS_RSS_AVERAGE);
- setValue(key, PSS_RSS_AVERAGE,
- (long)(((val*(double)count)+(avgUss*(double)inCount)) / (count+inCount)));
+ stats[statsIndex + PSS_RSS_AVERAGE] = (long)(((stats[statsIndex + PSS_RSS_AVERAGE]
+ * (double)count) + (avgRss * (double)inCount)) / (count + inCount));
- val = getValue(key, PSS_RSS_MAXIMUM);
- if (val < maxUss) {
- setValue(key, PSS_RSS_MAXIMUM, maxUss);
+ if (stats[statsIndex + PSS_RSS_MAXIMUM] < maxRss) {
+ stats[statsIndex + PSS_RSS_MAXIMUM] = maxRss;
}
}
}
+
+ public void writeStatsToProtoForKey(ProtoOutputStream proto, int key) {
+ final long[] stats = getArrayForKey(key);
+ final int statsIndex = SparseMappingTable.getIndexFromKey(key);
+ writeStatsToProto(proto, stats, statsIndex);
+ }
+
+ public static void writeStatsToProto(ProtoOutputStream proto, final long[] stats,
+ final int statsIndex) {
+ proto.write(ProcessStatsProto.State.SAMPLE_SIZE, stats[statsIndex + PSS_SAMPLE_COUNT]);
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.PSS,
+ stats[statsIndex + PSS_MINIMUM],
+ stats[statsIndex + PSS_AVERAGE],
+ stats[statsIndex + PSS_MAXIMUM]);
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.USS,
+ stats[statsIndex + PSS_USS_MINIMUM],
+ stats[statsIndex + PSS_USS_AVERAGE],
+ stats[statsIndex + PSS_USS_MAXIMUM]);
+ ProtoUtils.toAggStatsProto(proto, ProcessStatsProto.State.RSS,
+ stats[statsIndex + PSS_RSS_MINIMUM],
+ stats[statsIndex + PSS_RSS_AVERAGE],
+ stats[statsIndex + PSS_RSS_MAXIMUM]);
+ }
}
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index dc30205..eb369e1 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -17,12 +17,19 @@
package com.android.internal.os;
import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.BatteryManager;
+import android.os.BatteryManagerInternal;
import android.os.Binder;
+import android.os.OsProtoEnums;
+import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.format.DateFormat;
import android.util.ArrayMap;
-import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -31,9 +38,13 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BinderInternal.CallSession;
import com.android.internal.util.Preconditions;
+import com.android.server.LocalServices;
import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@@ -42,6 +53,7 @@
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.function.Function;
import java.util.function.ToDoubleFunction;
/**
@@ -70,39 +82,117 @@
private final Random mRandom;
private long mStartTime = System.currentTimeMillis();
- public BinderCallsStats(Random random) {
- this.mRandom = random;
+ // State updated by the broadcast receiver below.
+ private boolean mScreenInteractive;
+ private boolean mCharging;
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ switch (intent.getAction()) {
+ case Intent.ACTION_BATTERY_CHANGED:
+ mCharging = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
+ break;
+ case Intent.ACTION_SCREEN_ON:
+ mScreenInteractive = true;
+ break;
+ case Intent.ACTION_SCREEN_OFF:
+ mScreenInteractive = false;
+ break;
+ }
+ }
+ };
+
+ /** Injector for {@link BinderCallsStats}. */
+ public static class Injector {
+ public Random getRandomGenerator() {
+ return new Random();
+ }
+ }
+
+ public BinderCallsStats(Injector injector) {
+ this.mRandom = injector.getRandomGenerator();
+ }
+
+ public void systemReady(Context context) {
+ registerBroadcastReceiver(context);
+ setInitialState(queryScreenInteractive(context), queryIsCharging());
+ }
+
+ /**
+ * Listens for screen/battery state changes.
+ */
+ @VisibleForTesting
+ public void registerBroadcastReceiver(Context context) {
+ final IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_BATTERY_CHANGED);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
+ context.registerReceiver(mBroadcastReceiver, filter);
+ }
+
+ /**
+ * Sets the battery/screen initial state.
+ *
+ * This has to be updated *after* the broadcast receiver is installed.
+ */
+ @VisibleForTesting
+ public void setInitialState(boolean isScreenInteractive, boolean isCharging) {
+ this.mScreenInteractive = isScreenInteractive;
+ this.mCharging = isCharging;
+ // Data collected previously was not accurate since the battery/screen state was not set.
+ reset();
+ }
+
+ private boolean queryIsCharging() {
+ final BatteryManagerInternal batteryManager =
+ LocalServices.getService(BatteryManagerInternal.class);
+ if (batteryManager == null) {
+ Slog.wtf(TAG, "BatteryManager null while starting BinderCallsStatsService");
+ // Default to true to not collect any data.
+ return true;
+ } else {
+ return batteryManager.getPlugType() != OsProtoEnums.BATTERY_PLUGGED_NONE;
+ }
+ }
+
+ private boolean queryScreenInteractive(Context context) {
+ final PowerManager powerManager = context.getSystemService(PowerManager.class);
+ final boolean screenInteractive;
+ if (powerManager == null) {
+ Slog.wtf(TAG, "PowerManager null while starting BinderCallsStatsService",
+ new Throwable());
+ return true;
+ } else {
+ return powerManager.isInteractive();
+ }
}
@Override
+ @Nullable
public CallSession callStarted(Binder binder, int code) {
- return callStarted(binder.getClass().getName(), code, binder.getTransactionName(code));
- }
-
- private CallSession callStarted(String className, int code, @Nullable String methodName) {
- CallSession s = mCallSessionsPool.poll();
- if (s == null) {
- s = new CallSession();
+ if (mCharging) {
+ return null;
}
- s.className = className;
+ final CallSession s = obtainCallSession();
+ s.binderClass = binder.getClass();
s.transactionCode = code;
- s.methodName = methodName;
s.exceptionThrown = false;
s.cpuTimeStarted = -1;
s.timeStarted = -1;
-
- synchronized (mLock) {
- if (!mDetailedTracking && !shouldTrackCall()) {
- return s;
- }
-
+ if (mDetailedTracking || shouldRecordDetailedData()) {
s.cpuTimeStarted = getThreadTimeMicro();
s.timeStarted = getElapsedRealtimeMicro();
}
return s;
}
+ private CallSession obtainCallSession() {
+ CallSession s = mCallSessionsPool.poll();
+ return s == null ? new CallSession() : s;
+ }
+
@Override
public void callEnded(@Nullable CallSession s, int parcelRequestSize, int parcelReplySize) {
if (s == null) {
@@ -117,27 +207,36 @@
}
private void processCallEnded(CallSession s, int parcelRequestSize, int parcelReplySize) {
+ // Non-negative time signals we need to record data for this call.
+ final boolean recordCall = s.cpuTimeStarted >= 0;
+ final long duration;
+ final long latencyDuration;
+ if (recordCall) {
+ duration = getThreadTimeMicro() - s.cpuTimeStarted;
+ latencyDuration = getElapsedRealtimeMicro() - s.timeStarted;
+ } else {
+ duration = 0;
+ latencyDuration = 0;
+ }
+ final int callingUid = getCallingUid();
+
synchronized (mLock) {
- final int callingUid = getCallingUid();
- UidEntry uidEntry = mUidEntries.get(callingUid);
- if (uidEntry == null) {
- uidEntry = new UidEntry(callingUid);
- mUidEntries.put(callingUid, uidEntry);
+ // This was already checked in #callStart but check again while synchronized.
+ if (mCharging) {
+ return;
}
+
+ final UidEntry uidEntry = getUidEntry(callingUid);
uidEntry.callCount++;
- CallStat callStat = uidEntry.getOrCreate(s.className, s.transactionCode);
+ final CallStat callStat = uidEntry.getOrCreate(
+ s.binderClass, s.transactionCode, mScreenInteractive);
callStat.callCount++;
- // Non-negative time signals we need to record data for this call.
- final boolean recordCall = s.cpuTimeStarted >= 0;
if (recordCall) {
- final long duration = getThreadTimeMicro() - s.cpuTimeStarted;
- final long latencyDuration = getElapsedRealtimeMicro() - s.timeStarted;
uidEntry.cpuTimeMicros += duration;
uidEntry.recordedCallCount++;
callStat.recordedCallCount++;
- callStat.methodName = s.methodName;
callStat.cpuTimeMicros += duration;
callStat.maxCpuTimeMicros = Math.max(callStat.maxCpuTimeMicros, duration);
callStat.latencyMicros += latencyDuration;
@@ -154,6 +253,15 @@
}
}
+ private UidEntry getUidEntry(int uid) {
+ UidEntry uidEntry = mUidEntries.get(uid);
+ if (uidEntry == null) {
+ uidEntry = new UidEntry(uid);
+ mUidEntries.put(uid, uidEntry);
+ }
+ return uidEntry;
+ }
+
@Override
public void callThrewException(@Nullable CallSession s, Exception exception) {
if (s == null) {
@@ -166,15 +274,41 @@
if (mExceptionCounts.size() >= MAX_EXCEPTION_COUNT_SIZE) {
className = EXCEPTION_COUNT_OVERFLOW_NAME;
}
- Integer count = mExceptionCounts.get(className);
+ final Integer count = mExceptionCounts.get(className);
mExceptionCounts.put(className, count == null ? 1 : count + 1);
}
} catch (RuntimeException e) {
// Do not propagate the exception. We do not want to swallow original exception.
- Log.wtf(TAG, "Unexpected exception while updating mExceptionCounts", e);
+ Slog.wtf(TAG, "Unexpected exception while updating mExceptionCounts");
}
}
+ @Nullable
+ private Method getDefaultTransactionNameMethod(Class<? extends Binder> binder) {
+ try {
+ return binder.getMethod("getDefaultTransactionName", int.class);
+ } catch (NoSuchMethodException e) {
+ // The method might not be present for stubs not generated with AIDL.
+ return null;
+ }
+ }
+
+ @Nullable
+ private String resolveTransactionCode(Method getDefaultTransactionName, int transactionCode) {
+ if (getDefaultTransactionName == null) {
+ return null;
+ }
+
+ try {
+ return (String) getDefaultTransactionName.invoke(null, transactionCode);
+ } catch (IllegalAccessException | InvocationTargetException | ClassCastException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * This method is expensive to call.
+ */
public ArrayList<ExportedCallStat> getExportedCallStats() {
// We do not collect all the data if detailed tracking is off.
if (!mDetailedTracking) {
@@ -183,15 +317,16 @@
ArrayList<ExportedCallStat> resultCallStats = new ArrayList<>();
synchronized (mLock) {
- int uidEntriesSize = mUidEntries.size();
+ final int uidEntriesSize = mUidEntries.size();
for (int entryIdx = 0; entryIdx < uidEntriesSize; entryIdx++){
- UidEntry entry = mUidEntries.valueAt(entryIdx);
+ final UidEntry entry = mUidEntries.valueAt(entryIdx);
for (CallStat stat : entry.getCallStatsList()) {
ExportedCallStat exported = new ExportedCallStat();
exported.uid = entry.uid;
- exported.className = stat.className;
- exported.methodName = stat.methodName == null
- ? String.valueOf(stat.transactionCode) : stat.methodName;
+ exported.className = stat.binderClass.getName();
+ exported.binderClass = stat.binderClass;
+ exported.transactionCode = stat.transactionCode;
+ exported.screenInteractive = stat.screenInteractive;
exported.cpuTimeMicros = stat.cpuTimeMicros;
exported.maxCpuTimeMicros = stat.maxCpuTimeMicros;
exported.latencyMicros = stat.latencyMicros;
@@ -206,6 +341,35 @@
}
}
+ // Resolve codes outside of the lock since it can be slow.
+ ExportedCallStat previous = null;
+ // Cache the previous method/transaction code.
+ Method getDefaultTransactionName = null;
+ String previousMethodName = null;
+ resultCallStats.sort(BinderCallsStats::compareByBinderClassAndCode);
+ for (ExportedCallStat exported : resultCallStats) {
+ final boolean isClassDifferent = previous == null
+ || !previous.className.equals(exported.className);
+ if (isClassDifferent) {
+ getDefaultTransactionName = getDefaultTransactionNameMethod(exported.binderClass);
+ }
+
+ final boolean isCodeDifferent = previous == null
+ || previous.transactionCode != exported.transactionCode;
+ final String methodName;
+ if (isClassDifferent || isCodeDifferent) {
+ String resolvedCode = resolveTransactionCode(
+ getDefaultTransactionName, exported.transactionCode);
+ methodName = resolvedCode == null
+ ? String.valueOf(exported.transactionCode)
+ : resolvedCode;
+ } else {
+ methodName = previousMethodName;
+ }
+ previousMethodName = methodName;
+ exported.methodName = methodName;
+ }
+
return resultCallStats;
}
@@ -229,9 +393,9 @@
pw.print("Start time: ");
pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStartTime));
pw.println("Sampling interval period: " + mPeriodicSamplingInterval);
- List<UidEntry> entries = new ArrayList<>();
+ final List<UidEntry> entries = new ArrayList<>();
- int uidEntriesSize = mUidEntries.size();
+ final int uidEntriesSize = mUidEntries.size();
for (int i = 0; i < uidEntriesSize; i++) {
UidEntry e = mUidEntries.valueAt(i);
entries.add(e);
@@ -241,37 +405,40 @@
}
entries.sort(Comparator.<UidEntry>comparingDouble(value -> value.cpuTimeMicros).reversed());
- String datasetSizeDesc = verbose ? "" : "(top 90% by cpu time) ";
- StringBuilder sb = new StringBuilder();
- List<UidEntry> topEntries = verbose ? entries
+ final String datasetSizeDesc = verbose ? "" : "(top 90% by cpu time) ";
+ final StringBuilder sb = new StringBuilder();
+ final List<UidEntry> topEntries = verbose ? entries
: getHighestValues(entries, value -> value.cpuTimeMicros, 0.9);
pw.println("Per-UID raw data " + datasetSizeDesc
- + "(package/uid, call_desc, cpu_time_micros, max_cpu_time_micros, "
+ + "(package/uid, call_desc, screen_interactive, "
+ + "cpu_time_micros, max_cpu_time_micros, "
+ "latency_time_micros, max_latency_time_micros, exception_count, "
+ "max_request_size_bytes, max_reply_size_bytes, recorded_call_count, "
+ "call_count):");
- for (UidEntry uidEntry : topEntries) {
- for (CallStat e : uidEntry.getCallStatsList()) {
- sb.setLength(0);
- sb.append(" ")
- .append(uidToString(uidEntry.uid, appIdToPkgNameMap))
- .append(',').append(e)
- .append(',').append(e.cpuTimeMicros)
- .append(',').append(e.maxCpuTimeMicros)
- .append(',').append(e.latencyMicros)
- .append(',').append(e.maxLatencyMicros)
- .append(',').append(mDetailedTracking ? e.exceptionCount : '_')
- .append(',').append(mDetailedTracking ? e.maxRequestSizeBytes : '_')
- .append(',').append(mDetailedTracking ? e.maxReplySizeBytes : '_')
- .append(',').append(e.recordedCallCount)
- .append(',').append(e.callCount);
- pw.println(sb);
- }
+ final List<ExportedCallStat> exportedCallStats = getExportedCallStats();
+ exportedCallStats.sort(BinderCallsStats::compareByCpuDesc);
+ for (ExportedCallStat e : exportedCallStats) {
+ sb.setLength(0);
+ sb.append(" ")
+ .append(uidToString(e.uid, appIdToPkgNameMap))
+ .append(',').append(e.className)
+ .append('#').append(e.methodName)
+ .append(',').append(e.screenInteractive)
+ .append(',').append(e.cpuTimeMicros)
+ .append(',').append(e.maxCpuTimeMicros)
+ .append(',').append(e.latencyMicros)
+ .append(',').append(e.maxLatencyMicros)
+ .append(',').append(mDetailedTracking ? e.exceptionCount : '_')
+ .append(',').append(mDetailedTracking ? e.maxRequestSizeBytes : '_')
+ .append(',').append(mDetailedTracking ? e.maxReplySizeBytes : '_')
+ .append(',').append(e.recordedCallCount)
+ .append(',').append(e.callCount);
+ pw.println(sb);
}
pw.println();
pw.println("Per-UID Summary " + datasetSizeDesc
+ "(cpu_time, % of total cpu_time, recorded_call_count, call_count, package/uid):");
- List<UidEntry> summaryEntries = verbose ? entries
+ final List<UidEntry> summaryEntries = verbose ? entries
: getHighestValues(entries, value -> value.cpuTimeMicros, 0.9);
for (UidEntry entry : summaryEntries) {
String uidStr = uidToString(entry.uid, appIdToPkgNameMap);
@@ -286,7 +453,7 @@
pw.println();
pw.println("Exceptions thrown (exception_count, class_name):");
- List<Pair<String, Integer>> exceptionEntries = new ArrayList<>();
+ final List<Pair<String, Integer>> exceptionEntries = new ArrayList<>();
// We cannot use new ArrayList(Collection) constructor because MapCollections does not
// implement toArray method.
mExceptionCounts.entrySet().iterator().forEachRemaining(
@@ -303,9 +470,9 @@
}
private static String uidToString(int uid, Map<Integer, String> pkgNameMap) {
- int appId = UserHandle.getAppId(uid);
- String pkgName = pkgNameMap == null ? null : pkgNameMap.get(appId);
- String uidStr = UserHandle.formatUid(uid);
+ final int appId = UserHandle.getAppId(uid);
+ final String pkgName = pkgNameMap == null ? null : pkgNameMap.get(appId);
+ final String uidStr = UserHandle.formatUid(uid);
return pkgName == null ? uidStr : pkgName + '/' + uidStr;
}
@@ -321,7 +488,7 @@
return SystemClock.elapsedRealtimeNanos() / 1000;
}
- private boolean shouldTrackCall() {
+ private boolean shouldRecordDetailedData() {
return mRandom.nextInt() % mPeriodicSamplingInterval == 0;
}
@@ -368,15 +535,18 @@
public long maxRequestSizeBytes;
public long maxReplySizeBytes;
public long exceptionCount;
+
+ // Used internally.
+ Class<? extends Binder> binderClass;
+ int transactionCode;
}
@VisibleForTesting
public static class CallStat {
- public String className;
+ public Class<? extends Binder> binderClass;
public int transactionCode;
- // Method name might be null when we cannot resolve the transaction code. For instance, if
- // the binder was not generated by AIDL.
- public @Nullable String methodName;
+ // True if the screen was interactive when the call ended.
+ public boolean screenInteractive;
// Number of calls for which we collected data for. We do not record data for all the calls
// when sampling is on.
public long recordedCallCount;
@@ -397,24 +567,19 @@
public long maxReplySizeBytes;
public long exceptionCount;
- CallStat() {
- }
-
- CallStat(String className, int transactionCode) {
- this.className = className;
+ CallStat(Class<? extends Binder> binderClass, int transactionCode,
+ boolean screenInteractive) {
+ this.binderClass = binderClass;
this.transactionCode = transactionCode;
- }
-
- @Override
- public String toString() {
- return className + "#" + (methodName == null ? transactionCode : methodName);
+ this.screenInteractive = screenInteractive;
}
}
/** Key used to store CallStat object in a Map. */
public static class CallStatKey {
- public String className;
+ public Class<? extends Binder> binderClass;
public int transactionCode;
+ private boolean screenInteractive;
@Override
public boolean equals(Object o) {
@@ -422,15 +587,17 @@
return true;
}
- CallStatKey key = (CallStatKey) o;
+ final CallStatKey key = (CallStatKey) o;
return transactionCode == key.transactionCode
- && (className.equals(key.className));
+ && screenInteractive == key.screenInteractive
+ && (binderClass.equals(key.binderClass));
}
@Override
public int hashCode() {
- int result = className.hashCode();
+ int result = binderClass.hashCode();
result = 31 * result + transactionCode;
+ result = 31 * result + (screenInteractive ? 1231 : 1237);
return result;
}
}
@@ -457,17 +624,20 @@
private Map<CallStatKey, CallStat> mCallStats = new ArrayMap<>();
private CallStatKey mTempKey = new CallStatKey();
- CallStat getOrCreate(String className, int transactionCode) {
+ CallStat getOrCreate(Class<? extends Binder> binderClass, int transactionCode,
+ boolean screenInteractive) {
// Use a global temporary key to avoid creating new objects for every lookup.
- mTempKey.className = className;
+ mTempKey.binderClass = binderClass;
mTempKey.transactionCode = transactionCode;
+ mTempKey.screenInteractive = screenInteractive;
CallStat mapCallStat = mCallStats.get(mTempKey);
// Only create CallStat if it's a new entry, otherwise update existing instance
if (mapCallStat == null) {
- mapCallStat = new CallStat(className, transactionCode);
+ mapCallStat = new CallStat(binderClass, transactionCode, screenInteractive);
CallStatKey key = new CallStatKey();
- key.className = className;
+ key.binderClass = binderClass;
key.transactionCode = transactionCode;
+ key.screenInteractive = screenInteractive;
mCallStats.put(key, mapCallStat);
}
return mapCallStat;
@@ -476,17 +646,8 @@
/**
* Returns list of calls sorted by CPU time
*/
- public List<CallStat> getCallStatsList() {
- List<CallStat> callStats = new ArrayList<>(mCallStats.values());
- callStats.sort((o1, o2) -> {
- if (o1.cpuTimeMicros < o2.cpuTimeMicros) {
- return 1;
- } else if (o1.cpuTimeMicros > o2.cpuTimeMicros) {
- return -1;
- }
- return 0;
- });
- return callStats;
+ public Collection<CallStat> getCallStatsList() {
+ return mCallStats.values();
}
@Override
@@ -545,4 +706,21 @@
return result;
}
+ @VisibleForTesting
+ public BroadcastReceiver getBroadcastReceiver() {
+ return mBroadcastReceiver;
+ }
+
+ private static int compareByCpuDesc(
+ ExportedCallStat a, ExportedCallStat b) {
+ return Long.compare(b.cpuTimeMicros, a.cpuTimeMicros);
+ }
+
+ private static int compareByBinderClassAndCode(
+ ExportedCallStat a, ExportedCallStat b) {
+ int result = a.className.compareTo(b.className);
+ return result != 0
+ ? result
+ : Integer.compare(a.transactionCode, b.transactionCode);
+ }
}
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index 4b93c86..0155067 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -75,11 +75,9 @@
*/
public static class CallSession {
// Binder interface descriptor.
- public String className;
+ public Class<? extends Binder> binderClass;
// Binder transaction code.
public int transactionCode;
- // Binder transaction method name.
- public String methodName;
// CPU time at the beginning of the call.
long cpuTimeStarted;
// System time at the beginning of the call.
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 4ee950a..413f89d 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -132,13 +132,14 @@
*/
public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
- int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir) {
+ int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
+ String packageName) {
VM_HOOKS.preFork();
// Resets nice priority for zygote process.
resetNicePriority();
int pid = nativeForkAndSpecialize(
uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
- fdsToIgnore, startChildZygote, instructionSet, appDataDir);
+ fdsToIgnore, startChildZygote, instructionSet, appDataDir, packageName);
// Enable tracing as soon as possible for the child process.
if (pid == 0) {
Trace.setTracingEnabled(true, runtimeFlags);
@@ -152,7 +153,8 @@
native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
- int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir);
+ int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
+ String packageName);
/**
* Called to do any initialization before starting an application.
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 12761b9..b9c717f 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -239,7 +239,7 @@
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.runtimeFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.startChildZygote,
- parsedArgs.instructionSet, parsedArgs.appDataDir);
+ parsedArgs.instructionSet, parsedArgs.appDataDir, parsedArgs.packageName);
try {
if (pid == 0) {
@@ -426,6 +426,9 @@
/** from --invoke-with */
String invokeWith;
+ /** from --package-name */
+ String packageName;
+
/**
* Any args after and including the first non-option arg
* (or after a '--')
@@ -674,6 +677,8 @@
"Invalid log sampling rate: " + rateStr, nfe);
}
expectRuntimeArgs = false;
+ } else if (arg.startsWith("--package-name=")) {
+ packageName = arg.substring(arg.indexOf('=') + 1);
} else {
break;
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 2790324..616520f 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -140,14 +140,14 @@
void showShutdownUi(boolean isReboot, String reason);
- // Used to show the dialog when FingerprintService starts authentication
- void showFingerprintDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
- // Used to hide the dialog when a finger is authenticated
- void onFingerprintAuthenticated();
+ // Used to show the dialog when BiometricService starts authentication
+ void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
+ // Used to hide the dialog when a biometric is authenticated
+ void onBiometricAuthenticated();
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
- void onFingerprintHelp(String message);
+ void onBiometricHelp(String message);
// Used to set a message - the dialog will dismiss after a certain amount of time
- void onFingerprintError(String error);
- // Used to hide the fingerprint dialog when the authenticationclient is stopped
- void hideFingerprintDialog();
+ void onBiometricError(String error);
+ // Used to hide the biometric dialog when the AuthenticationClient is stopped
+ void hideBiometricDialog();
}
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index 159d49b..a79e15a 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -90,14 +90,14 @@
void showPinningEnterExitToast(boolean entering);
void showPinningEscapeToast();
- // Used to show the dialog when FingerprintService starts authentication
- void showFingerprintDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
- // Used to hide the dialog when a finger is authenticated
- void onFingerprintAuthenticated();
+ // Used to show the dialog when BiometricService starts authentication
+ void showBiometricDialog(in Bundle bundle, IBiometricPromptReceiver receiver);
+ // Used to hide the dialog when a biometric is authenticated
+ void onBiometricAuthenticated();
// Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
- void onFingerprintHelp(String message);
+ void onBiometricHelp(String message);
// Used to set a message - the dialog will dismiss after a certain amount of time
- void onFingerprintError(String error);
- // Used to hide the fingerprint dialog when the authenticationclient is stopped
- void hideFingerprintDialog();
+ void onBiometricError(String error);
+ // Used to hide the biometric dialog when the AuthenticationClient is stopped
+ void hideBiometricDialog();
}
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index c3d33ca8..4b66267 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -309,7 +309,7 @@
}
@SuppressWarnings("unchecked")
- public static @NonNull <T> T[] concat(Class<T> kind, @Nullable T[] a, @Nullable T[] b) {
+ public static @NonNull <T> T[] concatElements(Class<T> kind, @Nullable T[] a, @Nullable T[] b) {
final int an = (a != null) ? a.length : 0;
final int bn = (b != null) ? b.length : 0;
if (an == 0 && bn == 0) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 3d80f3d..6856e29 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -154,6 +154,7 @@
"android/graphics/Typeface.cpp",
"android/graphics/Utils.cpp",
"android/graphics/YuvToJpegEncoder.cpp",
+ "android/graphics/fonts/Font.cpp",
"android/graphics/pdf/PdfDocument.cpp",
"android/graphics/pdf/PdfEditor.cpp",
"android/graphics/pdf/PdfRenderer.cpp",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 0c625a7..1820888 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -140,6 +140,7 @@
extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env);
extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
+extern int register_android_graphics_fonts_Font(JNIEnv* env);
extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
@@ -1406,6 +1407,7 @@
REG_JNI(register_android_graphics_YuvImage),
REG_JNI(register_android_graphics_drawable_AnimatedVectorDrawable),
REG_JNI(register_android_graphics_drawable_VectorDrawable),
+ REG_JNI(register_android_graphics_fonts_Font),
REG_JNI(register_android_graphics_pdf_PdfDocument),
REG_JNI(register_android_graphics_pdf_PdfEditor),
REG_JNI(register_android_graphics_pdf_PdfRenderer),
diff --git a/core/jni/android/graphics/FontUtils.h b/core/jni/android/graphics/FontUtils.h
index 9eaaa49..9f6462e 100644
--- a/core/jni/android/graphics/FontUtils.h
+++ b/core/jni/android/graphics/FontUtils.h
@@ -20,6 +20,8 @@
#include <jni.h>
#include <memory>
+#include <minikin/Font.h>
+
namespace minikin {
class FontFamily;
} // namespace minikin
@@ -31,6 +33,11 @@
std::shared_ptr<minikin::FontFamily> family;
};
+struct FontWrapper {
+ FontWrapper(minikin::Font&& font) : font(std::move(font)) {}
+ minikin::Font font;
+};
+
// Utility wrapper for java.util.List
class ListHelper {
public:
diff --git a/core/jni/android/graphics/fonts/Font.cpp b/core/jni/android/graphics/fonts/Font.cpp
new file mode 100644
index 0000000..2d1d7a0
--- /dev/null
+++ b/core/jni/android/graphics/fonts/Font.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#define LOG_TAG "Minikin"
+
+#include <nativehelper/JNIHelp.h>
+#include <core_jni_helpers.h>
+
+#include "SkData.h"
+#include "SkFontMgr.h"
+#include "SkRefCnt.h"
+#include "SkTypeface.h"
+#include "GraphicsJNI.h"
+#include <nativehelper/ScopedUtfChars.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_util_AssetManager.h>
+#include <androidfw/AssetManager2.h>
+#include "Utils.h"
+#include "FontUtils.h"
+
+#include <hwui/MinikinSkia.h>
+#include <hwui/Typeface.h>
+#include <utils/FatVector.h>
+#include <minikin/FontFamily.h>
+
+#include <memory>
+
+namespace android {
+
+struct NativeFontBuilder {
+ std::vector<minikin::FontVariation> axes;
+};
+
+static inline NativeFontBuilder* toBuilder(jlong ptr) {
+ return reinterpret_cast<NativeFontBuilder*>(ptr);
+}
+
+static inline Asset* toAsset(jlong ptr) {
+ return reinterpret_cast<Asset*>(ptr);
+}
+
+static void releaseAsset(jlong asset) {
+ delete toAsset(asset);
+}
+
+static void releaseFont(jlong font) {
+ delete reinterpret_cast<FontWrapper*>(font);
+}
+
+static void release_global_ref(const void* /*data*/, void* context) {
+ JNIEnv* env = AndroidRuntime::getJNIEnv();
+ if (env == nullptr) {
+ JavaVMAttachArgs args;
+ args.version = JNI_VERSION_1_4;
+ args.name = "release_font_data";
+ args.group = nullptr;
+ jint result = AndroidRuntime::getJavaVM()->AttachCurrentThread(&env, &args);
+ if (result != JNI_OK) {
+ ALOGE("failed to attach to thread to release global ref.");
+ return;
+ }
+ }
+
+ jobject obj = reinterpret_cast<jobject>(context);
+ env->DeleteGlobalRef(obj);
+}
+
+// Regular JNI
+static jlong Font_Builder_getNativeAsset(
+ JNIEnv* env, jobject clazz, jobject assetMgr, jstring path, jboolean isAsset, jint cookie) {
+ NPE_CHECK_RETURN_ZERO(env, assetMgr);
+ NPE_CHECK_RETURN_ZERO(env, path);
+
+ Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(env, assetMgr);
+ if (mgr == nullptr) {
+ return 0;
+ }
+
+ ScopedUtfChars str(env, path);
+ if (str.c_str() == nullptr) {
+ return 0;
+ }
+
+ std::unique_ptr<Asset> asset;
+ {
+ ScopedLock<AssetManager2> locked_mgr(*mgr);
+ if (isAsset) {
+ asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER);
+ } else if (cookie > 0) {
+ // Valid java cookies are 1-based, but AssetManager cookies are 0-based.
+ asset = locked_mgr->OpenNonAsset(str.c_str(), static_cast<ApkAssetsCookie>(cookie - 1),
+ Asset::ACCESS_BUFFER);
+ } else {
+ asset = locked_mgr->OpenNonAsset(str.c_str(), Asset::ACCESS_BUFFER);
+ }
+ }
+
+ return reinterpret_cast<jlong>(asset.release());
+}
+
+// Regular JNI
+static jobject Font_Builder_getAssetBuffer(JNIEnv* env, jobject clazz, jlong nativeAsset) {
+ Asset* asset = toAsset(nativeAsset);
+ return env->NewDirectByteBuffer(const_cast<void*>(asset->getBuffer(false)), asset->getLength());
+}
+
+// CriticalNative
+static jlong Font_Builder_getReleaseNativeAssetFunc() {
+ return reinterpret_cast<jlong>(&releaseAsset);
+}
+
+// Regular JNI
+static jlong Font_Builder_initBuilder(JNIEnv*, jobject) {
+ return reinterpret_cast<jlong>(new NativeFontBuilder());
+}
+
+// Critical Native
+static void Font_Builder_addAxis(jlong builderPtr, jint tag, jfloat value) {
+ toBuilder(builderPtr)->axes.emplace_back(static_cast<minikin::AxisTag>(tag), value);
+}
+
+// Regular JNI
+static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jobject buffer,
+ jint weight, jboolean italic, jint ttcIndex) {
+ NPE_CHECK_RETURN_ZERO(env, buffer);
+ std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr));
+ const void* fontPtr = env->GetDirectBufferAddress(buffer);
+ if (fontPtr == nullptr) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
+ return 0;
+ }
+ jlong fontSize = env->GetDirectBufferCapacity(buffer);
+ if (fontSize <= 0) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "buffer size must not be zero or negative");
+ return 0;
+ }
+ jobject fontRef = MakeGlobalRefOrDie(env, buffer);
+ sk_sp<SkData> data(SkData::MakeWithProc(fontPtr, fontSize,
+ release_global_ref, reinterpret_cast<void*>(fontRef)));
+
+ uirenderer::FatVector<SkFontArguments::Axis, 2> skiaAxes;
+ for (const auto& axis : builder->axes) {
+ skiaAxes.emplace_back(SkFontArguments::Axis{axis.axisTag, axis.value});
+ }
+
+ std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(std::move(data)));
+
+ SkFontArguments params;
+ params.setCollectionIndex(ttcIndex);
+ params.setAxes(skiaAxes.data(), skiaAxes.size());
+
+ sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
+ sk_sp<SkTypeface> face(fm->makeFromStream(std::move(fontData), params));
+ if (face == nullptr) {
+ jniThrowException(env, "java/lang/IllegalArgumentException",
+ "Failed to create internal object. maybe invalid font data.");
+ return 0;
+ }
+ std::shared_ptr<minikin::MinikinFont> minikinFont =
+ std::make_shared<MinikinFontSkia>(std::move(face), fontPtr, fontSize, ttcIndex,
+ builder->axes);
+ minikin::Font font = minikin::Font::Builder(minikinFont).setWeight(weight)
+ .setSlant(static_cast<minikin::FontStyle::Slant>(italic)).build();
+ return reinterpret_cast<jlong>(new FontWrapper(std::move(font)));
+}
+
+// Critical Native
+static jlong Font_Builder_getReleaseNativeFont() {
+ return reinterpret_cast<jlong>(releaseFont);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const JNINativeMethod gFontBuilderMethods[] = {
+ { "nInitBuilder", "()J", (void*) Font_Builder_initBuilder },
+ { "nAddAxis", "(JIF)V", (void*) Font_Builder_addAxis },
+ { "nBuild", "(JLjava/nio/ByteBuffer;IZI)J", (void*) Font_Builder_build },
+ { "nGetReleaseNativeFont", "()J", (void*) Font_Builder_getReleaseNativeFont },
+
+ { "nGetNativeAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;ZI)J",
+ (void*) Font_Builder_getNativeAsset },
+ { "nGetAssetBuffer", "(J)Ljava/nio/ByteBuffer;", (void*) Font_Builder_getAssetBuffer },
+ { "nGetReleaseNativeAssetFunc", "()J", (void*) Font_Builder_getReleaseNativeAssetFunc },
+};
+
+int register_android_graphics_fonts_Font(JNIEnv* env) {
+ return RegisterMethodsOrDie(env, "android/graphics/fonts/Font$Builder", gFontBuilderMethods,
+ NELEM(gFontBuilderMethods));
+}
+
+}
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 3b024b4..db3bfe6 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -320,9 +320,12 @@
jintArray jcolors, jint colorIndex,
jshortArray jindices, jint indexIndex,
jint indexCount, jlong paintHandle) {
+
+ const int vertexCount = floatCount >> 1; // 2 floats per SkPoint
+
AutoJavaFloatArray vertA(env, jverts, vertIndex + floatCount);
AutoJavaFloatArray texA(env, jtexs, texIndex + floatCount);
- AutoJavaIntArray colorA(env, jcolors, colorIndex + floatCount);
+ AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount);
AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount);
const float* verts = vertA.ptr() + vertIndex;
@@ -337,7 +340,6 @@
indices = (const uint16_t*)(indexA.ptr() + indexIndex);
}
- int vertexCount = floatCount >> 1; // 2 floats per SkPoint
SkVertices::VertexMode mode = static_cast<SkVertices::VertexMode>(modeHandle);
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
get_canvas(canvasHandle)->drawVertices(SkVertices::MakeCopy(mode, vertexCount,
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 5b4b5f2..02d6adb 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -446,7 +446,7 @@
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
Rect crop(l, t, r, b);
- transaction->setCrop(ctrl, crop);
+ transaction->setCrop_legacy(ctrl, crop);
}
static void nativeSetFinalCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -456,7 +456,7 @@
SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
Rect crop(l, t, r, b);
- transaction->setFinalCrop(ctrl, crop);
+ transaction->setFinalCrop_legacy(ctrl, crop);
}
static void nativeSetLayerStack(JNIEnv* env, jclass clazz, jlong transactionObj,
@@ -799,7 +799,7 @@
{
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
- transaction->deferTransactionUntil(ctrl, handle, frameNumber);
+ transaction->deferTransactionUntil_legacy(ctrl, handle, frameNumber);
}
}
@@ -811,7 +811,7 @@
auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
- transaction->deferTransactionUntil(ctrl, barrier, frameNumber);
+ transaction->deferTransactionUntil_legacy(ctrl, barrier, frameNumber);
}
static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong transactionObj,
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 0022cf88..7380692 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -70,6 +70,7 @@
namespace {
using android::String8;
+using android::base::StringAppendF;
using android::base::StringPrintf;
using android::base::WriteStringToFile;
using android::base::GetBoolProperty;
@@ -79,6 +80,7 @@
static pid_t gSystemServerPid = 0;
+static const char kIsolatedStorage[] = "persist.sys.isolated_storage";
static const char kZygoteClassName[] = "com/android/internal/os/Zygote";
static jclass gZygoteClass;
static jmethodID gCallPostForkChildHooks;
@@ -379,10 +381,32 @@
return 0;
}
+static bool createPkgSandbox(uid_t uid, const char* package_name, std::string& pkg_sandbox_dir,
+ std::string* error_msg) {
+ // Create /mnt/user/0/package/<package-name>
+ userid_t user_id = multiuser_get_user_id(uid);
+ StringAppendF(&pkg_sandbox_dir, "/%d", user_id);
+ if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+ *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str());
+ return false;
+ }
+ StringAppendF(&pkg_sandbox_dir, "/package");
+ if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) {
+ *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str());
+ return false;
+ }
+ StringAppendF(&pkg_sandbox_dir, "/%s", package_name);
+ if (fs_prepare_dir(pkg_sandbox_dir.c_str(), 0755, uid, uid) != 0) {
+ *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", pkg_sandbox_dir.c_str());
+ return false;
+ }
+ return true;
+}
+
// Create a private mount namespace and bind mount appropriate emulated
// storage for the given user.
static bool MountEmulatedStorage(uid_t uid, jint mount_mode,
- bool force_mount_namespace, std::string* error_msg) {
+ bool force_mount_namespace, std::string* error_msg, const char* package_name) {
// See storage config details at http://source.android.com/tech/storage/
String8 storageSource;
@@ -408,27 +432,44 @@
return true;
}
- if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
- NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
- *error_msg = CREATE_ERROR("Failed to mount %s to /storage: %s",
- storageSource.string(),
- strerror(errno));
- return false;
- }
+ if (GetBoolProperty(kIsolatedStorage, false)) {
+ if (package_name == nullptr) {
+ return true;
+ }
- // Mount user-specific symlink helper into place
- userid_t user_id = multiuser_get_user_id(uid);
- const String8 userSource(String8::format("/mnt/user/%d", user_id));
- if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
- *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", userSource.string());
- return false;
- }
- if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
- NULL, MS_BIND, NULL)) == -1) {
- *error_msg = CREATE_ERROR("Failed to mount %s to /storage/self: %s",
- userSource.string(),
- strerror(errno));
- return false;
+ std::string pkgSandboxDir("/mnt/user");
+ if (!createPkgSandbox(uid, package_name, pkgSandboxDir, error_msg)) {
+ return false;
+ }
+ if (TEMP_FAILURE_RETRY(mount(pkgSandboxDir.c_str(), "/storage",
+ nullptr, MS_BIND | MS_REC | MS_SLAVE, nullptr)) == -1) {
+ *error_msg = CREATE_ERROR("Failed to mount %s to /storage: %s",
+ pkgSandboxDir.c_str(), strerror(errno));
+ return false;
+ }
+ } else {
+ if (TEMP_FAILURE_RETRY(mount(storageSource.string(), "/storage",
+ NULL, MS_BIND | MS_REC | MS_SLAVE, NULL)) == -1) {
+ *error_msg = CREATE_ERROR("Failed to mount %s to /storage: %s",
+ storageSource.string(),
+ strerror(errno));
+ return false;
+ }
+
+ // Mount user-specific symlink helper into place
+ userid_t user_id = multiuser_get_user_id(uid);
+ const String8 userSource(String8::format("/mnt/user/%d", user_id));
+ if (fs_prepare_dir(userSource.string(), 0751, 0, 0) == -1) {
+ *error_msg = CREATE_ERROR("fs_prepare_dir failed on %s", userSource.string());
+ return false;
+ }
+ if (TEMP_FAILURE_RETRY(mount(userSource.string(), "/storage/self",
+ NULL, MS_BIND, NULL)) == -1) {
+ *error_msg = CREATE_ERROR("Failed to mount %s to /storage/self: %s",
+ userSource.string(),
+ strerror(errno));
+ return false;
+ }
}
return true;
@@ -544,7 +585,7 @@
jlong permittedCapabilities, jlong effectiveCapabilities,
jint mount_external, jstring java_se_info, jstring java_se_name,
bool is_system_server, bool is_child_zygote, jstring instructionSet,
- jstring dataDir) {
+ jstring dataDir, jstring packageName) {
std::string error_msg;
auto fail_fn = [env, java_se_name, is_system_server](const std::string& msg)
@@ -594,7 +635,18 @@
ALOGW("Native bridge will not be used because dataDir == NULL.");
}
- if (!MountEmulatedStorage(uid, mount_external, use_native_bridge, &error_msg)) {
+ ScopedUtfChars* package_name = nullptr;
+ const char* package_name_c_str = nullptr;
+ if (packageName != nullptr) {
+ package_name = new ScopedUtfChars(env, packageName);
+ package_name_c_str = package_name->c_str();
+ } else if (is_system_server) {
+ package_name_c_str = "android";
+ }
+ bool success = MountEmulatedStorage(uid, mount_external, use_native_bridge, &error_msg,
+ package_name_c_str);
+ delete package_name;
+ if (!success) {
ALOGW("Failed to mount emulated storage: %s (%s)", error_msg.c_str(), strerror(errno));
if (errno == ENOTCONN || errno == EROFS) {
// When device is actively encrypting, we get ENOTCONN here
@@ -858,7 +910,7 @@
jint runtime_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote,
- jstring instructionSet, jstring appDataDir) {
+ jstring instructionSet, jstring appDataDir, jstring packageName) {
jlong capabilities = 0;
// Grant CAP_WAKE_ALARM to the Bluetooth process.
@@ -911,7 +963,7 @@
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
capabilities, capabilities,
mount_external, se_info, se_name, false,
- is_child_zygote == JNI_TRUE, instructionSet, appDataDir);
+ is_child_zygote == JNI_TRUE, instructionSet, appDataDir, packageName);
}
return pid;
}
@@ -925,7 +977,7 @@
SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
MOUNT_EXTERNAL_DEFAULT, NULL, NULL, true,
- false, NULL, NULL);
+ false, NULL, NULL, nullptr);
} else if (pid > 0) {
// The zygote process checks whether the child process has died or not.
ALOGI("System server process %d has been created", pid);
@@ -1006,7 +1058,7 @@
{ "nativeSecurityInit", "()V",
(void *) com_android_internal_os_Zygote_nativeSecurityInit },
{ "nativeForkAndSpecialize",
- "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
+ "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
(void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
(void *) com_android_internal_os_Zygote_nativeForkSystemServer },
diff --git a/core/proto/android/app/notificationmanager.proto b/core/proto/android/app/notificationmanager.proto
index e991688..183f9d3 100644
--- a/core/proto/android/app/notificationmanager.proto
+++ b/core/proto/android/app/notificationmanager.proto
@@ -42,9 +42,10 @@
REPEAT_CALLERS = 5;
// Alarms are prioritized.
ALARMS = 6;
- // Media, system, game (catch-all for non-never suppressible sounds) are
- // prioritized.
- MEDIA_SYSTEM_OTHER = 7;
+ // Media, game, voice navigation are prioritized.
+ MEDIA = 7;
+ // System (catch-all for non-never suppressible sounds) are prioritized.
+ SYSTEM = 8;
}
repeated Category priority_categories = 1;
@@ -64,10 +65,32 @@
// Whether notifications suppressed by DND should not interrupt visually
// (e.g. with notification lights or by turning the screen on) when the
// screen is off.
- SCREEN_OFF = 1;
+ // FULL_SCREEN_INTENT, AMBIENT, and LIGHTS should be used instead.
+ SCREEN_OFF = 1 [deprecated = true];
// Whether notifications suppressed by DND should not interrupt visually
// when the screen is on (e.g. by peeking onto the screen).
- SCREEN_ON = 2;
+ // PEEK should be used instead of ON.
+ SCREEN_ON = 2 [deprecated = true];
+ // Whether full screen intents} from notifications intercepted by DND
+ // are blocked.
+ FULL_SCREEN_INTENT = 3;
+ // Whether lights from notifications intercepted by DND are blocked.
+ LIGHTS = 4;
+ // Whether notifications intercepted by DND are prevented from peeking.
+ PEEK = 5;
+ // Whether notifications intercepted by DND are prevented from
+ // appearing in the status bar, on devices that support status bars.
+ STATUS_BAR = 6;
+ // Whether badges from notifications intercepted by DND are blocked on
+ // devices that support badging.
+ BADGE = 7;
+ // Whether notification intercepted by DND are prevented from appearing
+ // on ambient displays on devices that support ambient display.
+ AMBIENT = 8;
+ // Whether notification intercepted by DND are prevented from appearing
+ // in notification list views like the notification shade or lockscreen
+ // on devices that support those views.
+ NOTIFICATION_LIST = 9;
}
repeated SuppressedVisualEffect suppressed_visual_effects = 4;
}
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index ed7316a..040e36a 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -745,7 +745,7 @@
optional SettingProto car_dock = 1;
optional SettingProto car_undock = 2;
- optional SettingProto charging_sounds_enabled = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ reserved 3; // Moved to secure settings Sound.charging_sounds_enabled
optional SettingProto charging_started = 4;
optional SettingProto desk_dock = 5;
optional SettingProto desk_undock = 6;
@@ -941,12 +941,8 @@
optional SettingProto mode = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto mode_ringer_level = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto mode_config_etag = 3;
- // If 0, turning on dnd manually will last indefinitely. Else if
- // non-negative, turning on dnd manually will last for this many minutes.
- // Else (if negative), turning on dnd manually will surface a dialog that
- // prompts user to specify a duration.
- optional SettingProto duration = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_zen_upgrade_notification = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ reserved 4; // Moved to secure settings Zen.duration
+ reserved 5; // Moved to secure settings Zen.show_zen_upgrade_notification
}
optional Zen zen = 138;
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 237efd8..f2e8c70 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -300,6 +300,7 @@
optional SettingProto enabled_policy_access_packages = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto badging = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto show_note_about_notification_hiding = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto in_call_notification_enabled = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Notification notification = 41;
@@ -404,6 +405,15 @@
optional SettingProto skip_first_use_hints = 52 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto sleep_timeout = 53 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto sms_default_application = 54 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Sounds {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto charging_sounds_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto charging_vibration_enabled = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Sounds sounds = 72;
+
// Defines whether managed profile ringtones should be synced from its
// parent profile.
optional SettingProto sync_parent_sounds = 55 [ (android.privacy).dest = DEST_AUTOMATIC ];
@@ -484,7 +494,22 @@
optional SettingProto wake_gesture_enabled = 68 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ message Zen {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // If 0, turning on dnd manually will last indefinitely. Else if
+ // non-negative, turning on dnd manually will last for this many minutes.
+ // Else (if negative), turning on dnd manually will surface a dialog that
+ // prompts user to specify a duration.
+ optional SettingProto duration = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_zen_upgrade_notification = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_zen_settings_suggestion = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto settings_updated = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto settings_suggestion_viewed = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Zen zen = 71;
+
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 71;
+ // Next tag = 73;
}
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index ebf751c..52c76cc 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -62,6 +62,8 @@
optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1;
repeated ActivityDisplayProto displays = 2;
optional KeyguardControllerProto keyguard_controller = 3;
+ // TODO(b/111541062): Focused stack and resumed activity are now per-display. Topmost instances
+ // can be obtained from top display and these fields can be removed.
optional int32 focused_stack_id = 4;
optional .com.android.server.wm.IdentifierProto resumed_activity = 5;
// Whether or not the home activity is the recents activity. This is needed for the CTS tests to
@@ -77,6 +79,8 @@
optional .com.android.server.wm.ConfigurationContainerProto configuration_container = 1;
optional int32 id = 2;
repeated ActivityStackProto stacks = 3;
+ optional int32 focused_stack_id = 4;
+ optional .com.android.server.wm.IdentifierProto resumed_activity = 5;
}
message ActivityStackProto {
diff --git a/core/proto/android/service/procstats.proto b/core/proto/android/service/procstats.proto
index 15ede0c..b2a88b7 100644
--- a/core/proto/android/service/procstats.proto
+++ b/core/proto/android/service/procstats.proto
@@ -174,4 +174,8 @@
optional android.util.AggStats rss = 8;
}
repeated State states = 5;
+
+ // Total time process has been running... screen_state, memory_state, and process_state
+ // will not be set.
+ optional State total_running_state = 6;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c2ff9c9..6a3487c1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -606,6 +606,14 @@
<protected-broadcast android:name="android.intent.action.DOCK_IDLE" />
<protected-broadcast android:name="android.intent.action.DOCK_ACTIVE" />
+ <!-- Added in Q -->
+
+ <!-- For CarIdlenessTracker -->
+ <protected-broadcast android:name="com.android.server.jobscheduler.GARAGE_MODE_ON" />
+ <protected-broadcast android:name="com.android.server.jobscheduler.GARAGE_MODE_OFF" />
+ <protected-broadcast android:name="com.android.server.jobscheduler.FORCE_IDLE" />
+ <protected-broadcast android:name="com.android.server.jobscheduler.UNFORCE_IDLE" />
+
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
<!-- ====================================================================== -->
@@ -3500,6 +3508,10 @@
<permission android:name="android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE"
android:protectionLevel="signature" />
+ <!-- @hide Internal permission to allows an application to access card content provider. -->
+ <permission android:name="android.permission.WRITE_SETTINGS_HOMEPAGE_DATA"
+ android:protectionLevel="signature|privileged" />
+
<!-- @SystemApi Allows applications to set a live wallpaper.
@hide XXX Change to signature once the picker is moved to its
own apk as Ghod Intended. -->
diff --git a/core/res/res/values-night/themes_package_installer.xml b/core/res/res/values-night/themes_package_installer.xml
new file mode 100644
index 0000000..0ad2bdc
--- /dev/null
+++ b/core/res/res/values-night/themes_package_installer.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2018 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.
+ -->
+
+<!-- themes for the permission grant dialog. -->
+<resources>
+ <style name="Theme.DeviceDefault.PermissionGrantApp"
+ parent="@style/Theme.DeviceDefault.Panel">
+ <item name="windowIsFloating">false</item>
+ <item name="windowTranslucentStatus">true</item>
+ <item name="backgroundDimEnabled">true</item>
+ <item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
+ </style>
+
+ <style name="Theme.DeviceDefault.PermissionGrant"
+ parent="@style/Theme.DeviceDefault.Dialog">
+ <item name="titleTextStyle">@style/PermissionGrantTitleMessage</item>
+ <item name="radioButtonStyle">@style/PermissionGrantRadioButton</item>
+ <item name="checkboxStyle">@style/PermissionGrantCheckbox</item>
+ <item name="buttonBarStyle">@style/PermissionGrantButtonBar</item>
+ </style>
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 44eea30c..2f710bf 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -3113,6 +3113,9 @@
the alpha channel of the outlineAmbientShadowColor (typically opaque), and the
{@link android.R.attr#ambientShadowAlpha} theme attribute. -->
<attr name="outlineAmbientShadowColor" format="color" />
+
+ <!-- Whether to allow the rendering system to force this View to render as light-on-dark. -->
+ <attr name="allowForceDark" format="boolean" />
</declare-styleable>
<!-- Attributes that can be assigned to a tag for a particular View. -->
@@ -7863,8 +7866,7 @@
wallpaper. -->
<attr name="showMetadataInPreview" format="boolean" />
- <!-- Wallpapers optimized and capable of drawing in ambient mode will return true.
- @hide -->
+ <!-- Wallpapers optimized and capable of drawing in ambient mode will return true. -->
<attr name="supportsAmbientMode" format="boolean" />
</declare-styleable>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3053fa1..474c62d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -551,9 +551,6 @@
radio is unable to find any MCC information to infer wifi country code from -->
<bool translatable="false" name="config_wifi_revert_country_code_on_cellular_loss">false</bool>
- <!-- Boolean indicating whether or not wifi firmware debugging is enabled -->
- <bool translatable="false" name="config_wifi_enable_wifi_firmware_debugging">true</bool>
-
<!-- Integer size limit, in KB, for a single WifiLogger ringbuffer, in default logging mode -->
<integer translatable="false" name="config_wifi_logger_ring_buffer_default_size_limit_kb">32</integer>
@@ -593,10 +590,6 @@
<integer translatable="false" name="config_wifi_framework_wifi_score_entry_rssi_threshold_24GHz">-80</integer>
<integer translatable="false" name="config_wifi_framework_wifi_score_low_rssi_threshold_24GHz">-73</integer>
<integer translatable="false" name="config_wifi_framework_wifi_score_good_rssi_threshold_24GHz">-60</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_bad_link_speed_24">6</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_bad_link_speed_5">12</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_24">24</integer>
- <integer translatable="false" name="config_wifi_framework_wifi_score_good_link_speed_5">36</integer>
<!-- Integer delay in milliseconds before shutting down soft AP when there
are no connected devices. Framework will enforce a minimum limit on
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 6189971..e25bb79 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2907,6 +2907,8 @@
<public name="opticalInsetTop" />
<public name="opticalInsetRight" />
<public name="opticalInsetBottom" />
+ <public name="allowForceDark" />
+ <public name="supportsAmbientMode" />
</public-group>
<public-group type="style" first-id="0x010302e2">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8847ec8..15331d64 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1399,11 +1399,11 @@
<!-- Content description which should be used for the fingerprint icon. -->
<string name="fingerprint_icon_content_description">Fingerprint icon</string>
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50] -->
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=70] -->
<string name="permlab_manageFace">manage face authentication hardware</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=90] -->
<string name="permdesc_manageFace">Allows the app to invoke methods to add and delete facial templates for use.</string>
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50] -->
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=70] -->
<string name="permlab_useFaceAuthentication">use face authentication hardware</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=90] -->
<string name="permdesc_useFaceAuthentication">Allows the app to use face authentication hardware for authentication</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 1c66b2b..e47ea71 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -346,7 +346,6 @@
<java-symbol type="integer" name="config_wifi_framework_sar_near_body_event_id" />
<java-symbol type="bool" name="config_wifi_enable_disconnection_debounce" />
<java-symbol type="bool" name="config_wifi_revert_country_code_on_cellular_loss" />
- <java-symbol type="bool" name="config_wifi_enable_wifi_firmware_debugging" />
<java-symbol type="integer" name="config_wifi_logger_ring_buffer_default_size_limit_kb" />
<java-symbol type="integer" name="config_wifi_logger_ring_buffer_verbose_size_limit_kb" />
<java-symbol type="bool" name="config_wifi_turn_off_during_emergency_call" />
@@ -394,10 +393,6 @@
<java-symbol type="integer" name="config_wifi_framework_wifi_score_entry_rssi_threshold_5GHz" />
<java-symbol type="integer" name="config_wifi_framework_wifi_score_low_rssi_threshold_5GHz" />
<java-symbol type="integer" name="config_wifi_framework_wifi_score_good_rssi_threshold_5GHz" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_link_speed_24" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_bad_link_speed_5" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_24" />
- <java-symbol type="integer" name="config_wifi_framework_wifi_score_good_link_speed_5" />
<java-symbol type="integer" name="config_wifi_framework_scan_result_rssi_level_patchup_value" />
<java-symbol type="integer" name="config_wifi_framework_current_network_boost" />
<java-symbol type="string" name="config_wifi_random_mac_oui" />
diff --git a/core/res/res/values/themes_package_installer.xml b/core/res/res/values/themes_package_installer.xml
index a6341dc..3bc93cd 100644
--- a/core/res/res/values/themes_package_installer.xml
+++ b/core/res/res/values/themes_package_installer.xml
@@ -17,7 +17,7 @@
<!-- themes for the permission grant dialog. -->
<resources>
- <style name="Theme.DeviceDefault.Light.Panel.PermissionGrantApp"
+ <style name="Theme.DeviceDefault.PermissionGrantApp"
parent="@style/Theme.DeviceDefault.Light.Panel">
<item name="windowIsFloating">false</item>
<item name="windowTranslucentStatus">true</item>
@@ -25,7 +25,7 @@
<item name="windowAnimationStyle">@style/Animation.Material.Dialog</item>
</style>
- <style name="Theme.DeviceDefault.Light.Dialog.PermissionGrant"
+ <style name="Theme.DeviceDefault.PermissionGrant"
parent="@style/Theme.DeviceDefault.Light.Dialog">
<item name="titleTextStyle">@style/PermissionGrantTitleMessage</item>
<item name="radioButtonStyle">@style/PermissionGrantRadioButton</item>
diff --git a/core/tests/coretests/src/android/database/DatabaseUtilsTest.java b/core/tests/coretests/src/android/database/DatabaseUtilsTest.java
new file mode 100644
index 0000000..7c206d7
--- /dev/null
+++ b/core/tests/coretests/src/android/database/DatabaseUtilsTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 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.database;
+
+import static android.database.DatabaseUtils.bindSelection;
+
+import static org.junit.Assert.assertEquals;
+
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class DatabaseUtilsTest {
+ private static final Object[] ARGS = { "baz", 4, null };
+
+ @Test
+ public void testBindSelection_none() throws Exception {
+ assertEquals(null,
+ bindSelection(null, ARGS));
+ assertEquals("",
+ bindSelection("", ARGS));
+ assertEquals("foo=bar",
+ bindSelection("foo=bar", ARGS));
+ }
+
+ @Test
+ public void testBindSelection_normal() throws Exception {
+ assertEquals("foo='baz'",
+ bindSelection("foo=?", ARGS));
+ assertEquals("foo='baz' AND bar=4",
+ bindSelection("foo=? AND bar=?", ARGS));
+ assertEquals("foo='baz' AND bar=4 AND meow=NULL",
+ bindSelection("foo=? AND bar=? AND meow=?", ARGS));
+ }
+
+ @Test
+ public void testBindSelection_whitespace() throws Exception {
+ assertEquals("BETWEEN 5 AND 10",
+ bindSelection("BETWEEN? AND ?", 5, 10));
+ assertEquals("IN 'foo'",
+ bindSelection("IN?", "foo"));
+ }
+
+ @Test
+ public void testBindSelection_indexed() throws Exception {
+ assertEquals("foo=10 AND bar=11 AND meow=1",
+ bindSelection("foo=?10 AND bar=? AND meow=?1",
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
+ }
+}
diff --git a/core/tests/coretests/src/android/os/WorkSourceTest.java b/core/tests/coretests/src/android/os/WorkSourceTest.java
index 952a64d..425ab89 100644
--- a/core/tests/coretests/src/android/os/WorkSourceTest.java
+++ b/core/tests/coretests/src/android/os/WorkSourceTest.java
@@ -378,6 +378,17 @@
assertEquals(75, ws1.getWorkChains().get(0).getAttributionUid());
}
+ public void testRemove_fromSameWorkSource() {
+ WorkSource ws1 = new WorkSource(50, "foo");
+ WorkSource ws2 = ws1;
+ ws2.add(ws1);
+ assertTrue(ws2.remove(ws1));
+
+ assertEquals(0, ws1.size());
+ assertEquals(50, ws1.get(0));
+ assertEquals("foo", ws1.getName(0));
+ }
+
public void testTransferWorkChains() {
WorkSource ws1 = new WorkSource();
WorkChain wc1 = ws1.createWorkChain().addNode(100, "tag");
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 37dec13..5542f00 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -383,16 +383,14 @@
Settings.Global.SETUP_PREPAID_DATA_SERVICE_URL,
Settings.Global.SETUP_PREPAID_DETECTION_REDIR_HOST,
Settings.Global.SETUP_PREPAID_DETECTION_TARGET_URL,
+ Settings.Global.SETTINGS_USE_EXTERNAL_PROVIDER_API,
+ Settings.Global.SETTINGS_USE_PSD_API,
Settings.Global.SHORTCUT_MANAGER_CONSTANTS,
Settings.Global.SHOW_FIRST_CRASH_DIALOG,
Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG,
Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS,
Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG,
Settings.Global.SHOW_TEMPERATURE_WARNING,
- Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION,
- Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION,
- Settings.Global.ZEN_SETTINGS_UPDATED,
- Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED,
Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
@@ -488,6 +486,7 @@
Settings.Global.WIFI_SAVED_STATE,
Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE,
Settings.Global.WIFI_SCAN_INTERVAL_WHEN_P2P_CONNECTED_MS,
+ Settings.Global.WIFI_SCAN_THROTTLE_ENABLED,
Settings.Global.WIFI_SCORE_PARAMS,
Settings.Global.WIFI_SLEEP_POLICY,
Settings.Global.WIFI_SUPPLICANT_SCAN_INTERVAL_MS,
@@ -495,8 +494,8 @@
Settings.Global.WIFI_VERBOSE_LOGGING_ENABLED,
Settings.Global.WIFI_WATCHDOG_ON,
Settings.Global.WIMAX_NETWORKS_AVAILABLE_NOTIFICATION_ON,
- Settings.Global.WINDOW_ANIMATION_SCALE,
Settings.Global.CHARGING_STARTED_SOUND,
+ Settings.Global.WINDOW_ANIMATION_SCALE,
Settings.Global.WTF_IS_FATAL,
Settings.Global.ZEN_MODE,
Settings.Global.ZEN_MODE_CONFIG_ETAG,
@@ -708,3 +707,4 @@
}
}
+
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
index 993378d..ec80d20 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
@@ -543,6 +543,27 @@
}
}
+ @Test
+ public void addA11yFocusNodeBeforeFocusClearedEvent_previousA11yFocusNodeGetsRefreshed() {
+ AccessibilityNodeInfo nodeInfo1 = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1);
+ nodeInfo1.setAccessibilityFocused(true);
+ mAccessibilityCache.add(nodeInfo1);
+ AccessibilityNodeInfo nodeInfo2 = getNodeWithA11yAndWindowId(OTHER_VIEW_ID, WINDOW_ID_1);
+ nodeInfo2.setAccessibilityFocused(true);
+ mAccessibilityCache.add(nodeInfo2);
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUS_CLEARED);
+ event.setSource(getMockViewWithA11yAndWindowIds(SINGLE_VIEW_ID, WINDOW_ID_1));
+ mAccessibilityCache.onAccessibilityEvent(event);
+ event.recycle();
+ try {
+ verify(mAccessibilityNodeRefresher).refreshNode(nodeInfo1, true);
+ } finally {
+ nodeInfo1.recycle();
+ nodeInfo2.recycle();
+ }
+ }
+
private void assertNodeIsRefreshedWithEventType(int eventType, int contentChangeTypes) {
AccessibilityNodeInfo nodeInfo = getNodeWithA11yAndWindowId(SINGLE_VIEW_ID, WINDOW_ID_1);
mAccessibilityCache.add(nodeInfo);
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index 44b1f08..0dd7685 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -119,6 +119,10 @@
return false;
}
+ public int getSoftKeyboardShowMode() {
+ return 0;
+ }
+
public void setSoftKeyboardCallbackEnabled(boolean enabled) {}
public boolean isAccessibilityButtonAvailable() {
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 20dc872..2f83190 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -16,7 +16,11 @@
package com.android.internal.os;
+import android.content.Context;
+import android.content.Intent;
+import android.os.BatteryManager;
import android.os.Binder;
+import android.os.OsProtoEnums;
import android.platform.test.annotations.Presubmit;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -31,6 +35,7 @@
import java.io.PrintWriter;
import java.io.StringWriter;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -62,11 +67,11 @@
assertEquals(1, uidEntries.size());
BinderCallsStats.UidEntry uidEntry = uidEntries.get(TEST_UID);
Assert.assertNotNull(uidEntry);
- List<BinderCallsStats.CallStat> callStatsList = uidEntry.getCallStatsList();
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
assertEquals(1, uidEntry.callCount);
assertEquals(1, uidEntry.recordedCallCount);
assertEquals(10, uidEntry.cpuTimeMicros);
- assertEquals(binder.getClass().getName(), callStatsList.get(0).className);
+ assertEquals(binder.getClass(), callStatsList.get(0).binderClass);
assertEquals(1, callStatsList.get(0).transactionCode);
// CPU usage is sampled, should not be tracked here.
@@ -85,7 +90,7 @@
assertEquals(3, uidEntry.callCount);
assertEquals(1, uidEntry.recordedCallCount);
// Still sampled even for another API.
- callStatsList = uidEntry.getCallStatsList();
+ callStatsList = new ArrayList(uidEntry.getCallStatsList());
assertEquals(2, callStatsList.size());
}
@@ -105,12 +110,12 @@
Assert.assertNotNull(uidEntry);
assertEquals(1, uidEntry.callCount);
assertEquals(10, uidEntry.cpuTimeMicros);
- assertEquals(1, uidEntry.getCallStatsList().size());
+ assertEquals(1, new ArrayList(uidEntry.getCallStatsList()).size());
- List<BinderCallsStats.CallStat> callStatsList = uidEntry.getCallStatsList();
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
assertEquals(1, callStatsList.get(0).callCount);
assertEquals(10, callStatsList.get(0).cpuTimeMicros);
- assertEquals(binder.getClass().getName(), callStatsList.get(0).className);
+ assertEquals(binder.getClass(), callStatsList.get(0).binderClass);
assertEquals(1, callStatsList.get(0).transactionCode);
callSession = bcs.callStarted(binder, 1);
@@ -120,7 +125,7 @@
uidEntry = bcs.getUidEntries().get(TEST_UID);
assertEquals(2, uidEntry.callCount);
assertEquals(30, uidEntry.cpuTimeMicros);
- callStatsList = uidEntry.getCallStatsList();
+ callStatsList = new ArrayList(uidEntry.getCallStatsList());
assertEquals(1, callStatsList.size());
callSession = bcs.callStarted(binder, 2);
@@ -131,7 +136,7 @@
// This is the first transaction of a new type, so the real CPU time will be measured
assertEquals(80, uidEntry.cpuTimeMicros);
- callStatsList = uidEntry.getCallStatsList();
+ callStatsList = new ArrayList(uidEntry.getCallStatsList());
assertEquals(2, callStatsList.size());
}
@@ -182,7 +187,7 @@
assertEquals(3, uidEntry.callCount);
assertEquals(60 /* 10 + 50 */, uidEntry.cpuTimeMicros);
- List<BinderCallsStats.CallStat> callStatsList = uidEntry.getCallStatsList();
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
assertEquals(1, callStatsList.size());
BinderCallsStats.CallStat callStats = callStatsList.get(0);
assertEquals(3, callStats.callCount);
@@ -216,7 +221,7 @@
assertEquals(1, uidEntry.recordedCallCount);
assertEquals(10, uidEntry.cpuTimeMicros);
- List<BinderCallsStats.CallStat> callStatsList = uidEntry.getCallStatsList();
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
assertEquals(2, callStatsList.size());
BinderCallsStats.CallStat callStats = callStatsList.get(0);
@@ -233,27 +238,79 @@
assertEquals(0, callStats.maxCpuTimeMicros);
}
+ private static class BinderWithGetTransactionName extends Binder {
+ public static String getDefaultTransactionName(int code) {
+ return "resolved";
+ }
+ }
+
+ private static class AnotherBinderWithGetTransactionName extends Binder {
+ public static String getDefaultTransactionName(int code) {
+ return "foo" + code;
+ }
+ }
+
@Test
public void testTransactionCodeResolved() {
TestBinderCallsStats bcs = new TestBinderCallsStats();
bcs.setDetailedTracking(true);
- Binder binder = new Binder() {
- @Override
- public String getTransactionName(int code) {
- return "resolved";
- }
- };
+ Binder binder = new BinderWithGetTransactionName();
CallSession callSession = bcs.callStarted(binder, 1);
bcs.time += 10;
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
- List<BinderCallsStats.CallStat> callStatsList =
- bcs.getUidEntries().get(TEST_UID).getCallStatsList();
- assertEquals(1, callStatsList.get(0).transactionCode);
+ List<BinderCallsStats.ExportedCallStat> callStatsList =
+ bcs.getExportedCallStats();
assertEquals("resolved", callStatsList.get(0).methodName);
}
@Test
+ public void testMultipleTransactionCodeResolved() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+
+ Binder binder = new AnotherBinderWithGetTransactionName();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ Binder binder2 = new BinderWithGetTransactionName();
+ callSession = bcs.callStarted(binder2, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ callSession = bcs.callStarted(binder, 2);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ List<BinderCallsStats.ExportedCallStat> callStatsList =
+ bcs.getExportedCallStats();
+ assertEquals("foo1", callStatsList.get(0).methodName);
+ assertEquals(AnotherBinderWithGetTransactionName.class.getName(),
+ callStatsList.get(0).className);
+ assertEquals("foo2", callStatsList.get(1).methodName);
+ assertEquals(AnotherBinderWithGetTransactionName.class.getName(),
+ callStatsList.get(1).className);
+ assertEquals("resolved", callStatsList.get(2).methodName);
+ assertEquals(BinderWithGetTransactionName.class.getName(),
+ callStatsList.get(2).className);
+ }
+
+ @Test
+ public void testResolvingCodeDoesNotThrowWhenMethodNotPresent() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ List<BinderCallsStats.ExportedCallStat> callStatsList =
+ bcs.getExportedCallStats();
+ assertEquals("1", callStatsList.get(0).methodName);
+ }
+
+ @Test
public void testParcelSize() {
TestBinderCallsStats bcs = new TestBinderCallsStats();
bcs.setDetailedTracking(true);
@@ -263,7 +320,7 @@
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
List<BinderCallsStats.CallStat> callStatsList =
- bcs.getUidEntries().get(TEST_UID).getCallStatsList();
+ new ArrayList(bcs.getUidEntries().get(TEST_UID).getCallStatsList());
assertEquals(REQUEST_SIZE, callStatsList.get(0).maxRequestSizeBytes);
assertEquals(REPLY_SIZE, callStatsList.get(0).maxReplySizeBytes);
@@ -283,7 +340,7 @@
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
List<BinderCallsStats.CallStat> callStatsList =
- bcs.getUidEntries().get(TEST_UID).getCallStatsList();
+ new ArrayList(bcs.getUidEntries().get(TEST_UID).getCallStatsList());
assertEquals(50, callStatsList.get(0).maxCpuTimeMicros);
}
@@ -302,7 +359,7 @@
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
List<BinderCallsStats.CallStat> callStatsList =
- bcs.getUidEntries().get(TEST_UID).getCallStatsList();
+ new ArrayList(bcs.getUidEntries().get(TEST_UID).getCallStatsList());
assertEquals(5, callStatsList.get(0).maxLatencyMicros);
}
@@ -339,6 +396,113 @@
}
@Test
+ public void testDataResetWhenInitialStateSet() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ bcs.setInitialState(true, true);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(0, uidEntries.size());
+ }
+
+ @Test
+ public void testScreenAndChargerInitialStates() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Binder binder = new Binder();
+ bcs.setInitialState(true /** screen iteractive */, false);
+
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.time += 10;
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ List<BinderCallsStats.CallStat> callStatsList =
+ new ArrayList(bcs.getUidEntries().get(TEST_UID).getCallStatsList());
+ assertEquals(true, callStatsList.get(0).screenInteractive);
+ }
+
+ @Test
+ public void testNoDataCollectedOnCharger() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED)
+ .putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_AC);
+ bcs.getBroadcastReceiver().onReceive(null, intent);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ assertEquals(0, bcs.getUidEntries().size());
+ }
+
+ @Test
+ public void testScreenOff() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ bcs.getBroadcastReceiver().onReceive(null, new Intent(Intent.ACTION_SCREEN_OFF));
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(1, uidEntries.size());
+ BinderCallsStats.UidEntry uidEntry = uidEntries.get(TEST_UID);
+ Assert.assertNotNull(uidEntry);
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
+ assertEquals(false, callStatsList.get(0).screenInteractive);
+ }
+
+ @Test
+ public void testScreenOn() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ bcs.getBroadcastReceiver().onReceive(null, new Intent(Intent.ACTION_SCREEN_ON));
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
+ assertEquals(1, uidEntries.size());
+ BinderCallsStats.UidEntry uidEntry = uidEntries.get(TEST_UID);
+ Assert.assertNotNull(uidEntry);
+ List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
+ assertEquals(true, callStatsList.get(0).screenInteractive);
+ }
+
+ @Test
+ public void testOnCharger() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED)
+ .putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_AC);
+ bcs.getBroadcastReceiver().onReceive(null, intent);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ assertEquals(0, bcs.getExportedCallStats().size());
+ }
+
+ @Test
+ public void testOnBattery() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ bcs.setDetailedTracking(true);
+ Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED)
+ .putExtra(BatteryManager.EXTRA_PLUGGED, OsProtoEnums.BATTERY_PLUGGED_NONE);
+ bcs.getBroadcastReceiver().onReceive(null, intent);
+ Binder binder = new Binder();
+ CallSession callSession = bcs.callStarted(binder, 1);
+ bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+ assertEquals(1, bcs.getExportedCallStats().size());
+ }
+
+ @Test
public void testDumpDoesNotThrowException() {
TestBinderCallsStats bcs = new TestBinderCallsStats();
bcs.setDetailedTracking(true);
@@ -366,6 +530,8 @@
public void testGetExportedStatsWhenDetailedTrackingEnabled() {
TestBinderCallsStats bcs = new TestBinderCallsStats();
bcs.setDetailedTracking(true);
+ bcs.getBroadcastReceiver().onReceive(null, new Intent(Intent.ACTION_SCREEN_ON));
+
Binder binder = new Binder();
CallSession callSession = bcs.callStarted(binder, 1);
bcs.time += 10;
@@ -377,6 +543,7 @@
assertEquals(TEST_UID, stat.uid);
assertEquals("android.os.Binder", stat.className);
assertEquals("1", stat.methodName);
+ assertEquals(true, stat.screenInteractive);
assertEquals(10, stat.cpuTimeMicros);
assertEquals(10, stat.maxCpuTimeMicros);
assertEquals(20, stat.latencyMicros);
@@ -388,6 +555,20 @@
assertEquals(0, stat.exceptionCount);
}
+ @Test
+ public void testGetExportedStatsWithoutCalls() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ Binder binder = new Binder();
+ assertEquals(0, bcs.getExportedCallStats().size());
+ }
+
+ @Test
+ public void testGetExportedExceptionsWithoutCalls() {
+ TestBinderCallsStats bcs = new TestBinderCallsStats();
+ Binder binder = new Binder();
+ assertEquals(0, bcs.getExceptionCounts().size());
+ }
+
static class TestBinderCallsStats extends BinderCallsStats {
int callingUid = TEST_UID;
long time = 1234;
@@ -395,11 +576,15 @@
TestBinderCallsStats() {
// Make random generator not random.
- super(new Random() {
- int mCallCount = 0;
+ super(new Injector() {
+ public Random getRandomGenerator() {
+ return new Random() {
+ int mCallCount = 0;
- public int nextInt() {
- return mCallCount++;
+ public int nextInt() {
+ return mCallCount++;
+ }
+ };
}
});
}
diff --git a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
index 6464ad3..39bb84a 100644
--- a/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/ArrayUtilsTest.java
@@ -16,6 +16,8 @@
package com.android.internal.util;
+import static com.android.internal.util.ArrayUtils.concatElements;
+
import static org.junit.Assert.assertArrayEquals;
import junit.framework.TestCase;
@@ -156,23 +158,23 @@
public void testConcatEmpty() throws Exception {
assertArrayEquals(new Long[] {},
- ArrayUtils.concat(Long.class, null, null));
+ concatElements(Long.class, null, null));
assertArrayEquals(new Long[] {},
- ArrayUtils.concat(Long.class, new Long[] {}, null));
+ concatElements(Long.class, new Long[] {}, null));
assertArrayEquals(new Long[] {},
- ArrayUtils.concat(Long.class, null, new Long[] {}));
+ concatElements(Long.class, null, new Long[] {}));
assertArrayEquals(new Long[] {},
- ArrayUtils.concat(Long.class, new Long[] {}, new Long[] {}));
+ concatElements(Long.class, new Long[] {}, new Long[] {}));
}
- public void testConcat() throws Exception {
+ public void testconcatElements() throws Exception {
assertArrayEquals(new Long[] { 1L },
- ArrayUtils.concat(Long.class, new Long[] { 1L }, new Long[] {}));
+ concatElements(Long.class, new Long[] { 1L }, new Long[] {}));
assertArrayEquals(new Long[] { 1L },
- ArrayUtils.concat(Long.class, new Long[] {}, new Long[] { 1L }));
+ concatElements(Long.class, new Long[] {}, new Long[] { 1L }));
assertArrayEquals(new Long[] { 1L, 2L },
- ArrayUtils.concat(Long.class, new Long[] { 1L }, new Long[] { 2L }));
+ concatElements(Long.class, new Long[] { 1L }, new Long[] { 2L }));
assertArrayEquals(new Long[] { 1L, 2L, 3L, 4L },
- ArrayUtils.concat(Long.class, new Long[] { 1L, 2L }, new Long[] { 3L, 4L }));
+ concatElements(Long.class, new Long[] { 1L, 2L }, new Long[] { 3L, 4L }));
}
}
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index 4e09c69..5cfae11 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -38,7 +38,7 @@
<hidden-api-whitelisted-app package="com.android.launcher3" />
<hidden-api-whitelisted-app package="com.android.mtp" />
<hidden-api-whitelisted-app package="com.android.musicfx" />
- <hidden-api-whitelisted-app package="com.android.packageinstaller" />
+ <hidden-api-whitelisted-app package="com.android.permissioncontroller" />
<hidden-api-whitelisted-app package="com.android.printservice.recommendation" />
<hidden-api-whitelisted-app package="com.android.printspooler" />
<hidden-api-whitelisted-app package="com.android.providers.blockednumber" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 434af14..f6587d3 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -133,13 +133,18 @@
</privapp-permissions>
<privapp-permissions package="com.android.packageinstaller">
- <permission name="android.permission.CLEAR_APP_CACHE"/>
<permission name="android.permission.DELETE_PACKAGES"/>
<permission name="android.permission.INSTALL_PACKAGES"/>
+ <permission name="android.permission.USE_RESERVED_DISK"/>
+ <permission name="android.permission.MANAGE_USERS"/>
+ <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+ </privapp-permissions>
+
+ <privapp-permissions package="com.android.permissioncontroller">
+ <permission name="android.permission.CLEAR_APP_CACHE"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"/>
<permission name="android.permission.UPDATE_APP_OPS_STATS"/>
- <permission name="android.permission.USE_RESERVED_DISK"/>
</privapp-permissions>
<privapp-permissions package="com.android.phone">
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index ffe6abc1..53e9826 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Canvas.VertexMode;
import android.text.GraphicsOperations;
import android.text.MeasuredParagraph;
@@ -44,6 +45,7 @@
* freed by NativeAllocation.
* @hide
*/
+ @UnsupportedAppUsage
protected long mNativeCanvasWrapper;
/**
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index c6f8415..cea6c1c 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.annotation.WorkerThread;
import android.content.res.ResourcesImpl;
import android.os.Parcel;
@@ -59,6 +60,7 @@
private static final long NATIVE_ALLOCATION_SIZE = 32;
// Convenience for JNI access
+ @UnsupportedAppUsage
private final long mNativePtr;
/**
@@ -75,9 +77,13 @@
*/
private boolean mRequestPremultiplied;
+ @UnsupportedAppUsage
private byte[] mNinePatchChunk; // may be null
+ @UnsupportedAppUsage
private NinePatch.InsetStruct mNinePatchInsets; // may be null
+ @UnsupportedAppUsage
private int mWidth;
+ @UnsupportedAppUsage
private int mHeight;
private boolean mRecycled;
@@ -99,11 +105,13 @@
* density when running old apps.
* @hide
*/
+ @UnsupportedAppUsage
public static void setDefaultDensity(int density) {
sDefaultDensity = density;
}
@SuppressWarnings("deprecation")
+ @UnsupportedAppUsage
static int getDefaultDensity() {
if (sDefaultDensity >= 0) {
return sDefaultDensity;
@@ -117,6 +125,7 @@
* int (pointer).
*/
// called from JNI
+ @UnsupportedAppUsage
Bitmap(long nativeBitmap, int width, int height, int density, boolean requestPremultiplied,
byte[] ninePatchChunk, NinePatch.InsetStruct ninePatchInsets) {
if (nativeBitmap == 0) {
@@ -158,6 +167,7 @@
* width/height values
*/
@SuppressWarnings("unused") // called from JNI
+ @UnsupportedAppUsage
void reinit(int width, int height, boolean requestPremultiplied) {
mWidth = width;
mHeight = height;
@@ -328,6 +338,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setNinePatchChunk(byte[] chunk) {
mNinePatchChunk = chunk;
}
@@ -523,6 +534,7 @@
*/
HARDWARE (7);
+ @UnsupportedAppUsage
final int nativeInt;
private static Config sConfigs[] = {
@@ -533,6 +545,7 @@
this.nativeInt = ni;
}
+ @UnsupportedAppUsage
static Config nativeToConfig(int ni) {
return sConfigs[ni];
}
@@ -667,6 +680,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Bitmap createAshmemBitmap() {
checkRecycled("Can't copy a recycled bitmap");
noteHardwareBitmapSlowCall();
@@ -685,6 +699,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public Bitmap createAshmemBitmap(Config config) {
checkRecycled("Can't copy a recycled bitmap");
noteHardwareBitmapSlowCall();
@@ -703,6 +718,7 @@
* currently PIXEL_FORMAT_RGBA_8888 is the only supported format
* @hide
*/
+ @UnsupportedAppUsage
public static Bitmap createHardwareBitmap(@NonNull GraphicBuffer graphicBuffer) {
return nativeCreateHardwareBitmap(graphicBuffer);
}
@@ -1500,6 +1516,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
static public int scaleFromDensity(int size, int sdensity, int tdensity) {
if (sdensity == DENSITY_NONE || tdensity == DENSITY_NONE || sdensity == tdensity) {
return size;
@@ -2032,6 +2049,7 @@
* @return {@link GraphicBuffer} which is internally used by hardware bitmap
* @hide
*/
+ @UnsupportedAppUsage
public GraphicBuffer createGraphicBufferHandle() {
return nativeCreateGraphicBufferHandle(mNativePtr);
}
@@ -2049,6 +2067,7 @@
private static native Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig);
private static native long nativeGetNativeFinalizer();
private static native void nativeRecycle(long nativeBitmap);
+ @UnsupportedAppUsage
private static native void nativeReconfigure(long nativeBitmap, int width, int height,
int config, boolean isPremultiplied);
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 7ea35e7..adab1a9c 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.os.Trace;
@@ -831,11 +832,15 @@
return decodeFileDescriptor(fd, null, null);
}
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
Rect padding, Options opts);
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
Rect padding, Options opts);
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeAsset(long nativeAsset, Rect padding, Options opts);
+ @UnsupportedAppUsage
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
int length, Options opts);
private static native boolean nativeIsSeekable(FileDescriptor fd);
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java
index 2da27c7..9b5027d 100644
--- a/graphics/java/android/graphics/BitmapRegionDecoder.java
+++ b/graphics/java/android/graphics/BitmapRegionDecoder.java
@@ -15,6 +15,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import java.io.FileDescriptor;
@@ -165,6 +166,7 @@
This can be called from JNI code.
*/
+ @UnsupportedAppUsage
private BitmapRegionDecoder(long decoder) {
mNativeBitmapRegionDecoder = decoder;
mRecycled = false;
@@ -267,6 +269,7 @@
private static native int nativeGetHeight(long lbm);
private static native void nativeClean(long lbm);
+ @UnsupportedAppUsage
private static native BitmapRegionDecoder nativeNewInstance(
byte[] data, int offset, int length, boolean isShareable);
private static native BitmapRegionDecoder nativeNewInstance(
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index 5577f53..bcf7229 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
/**
* Shader used to draw a bitmap as a texture. The bitmap can be repeated or
@@ -28,9 +29,12 @@
* @hide
*/
@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+ @UnsupportedAppUsage
public Bitmap mBitmap;
+ @UnsupportedAppUsage
private int mTileX;
+ @UnsupportedAppUsage
private int mTileY;
/**
diff --git a/graphics/java/android/graphics/Camera.java b/graphics/java/android/graphics/Camera.java
index 60588d0..3388941 100644
--- a/graphics/java/android/graphics/Camera.java
+++ b/graphics/java/android/graphics/Camera.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* A camera instance can be used to compute 3D transformations and
* generate a matrix that can be applied, for instance, on a
@@ -174,5 +176,6 @@
private native void nativeGetMatrix(long native_matrix);
private native void nativeApplyToCanvas(long native_canvas);
+ @UnsupportedAppUsage
long native_instance;
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index a465eea..ef58c8f 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.os.Build;
import dalvik.annotation.optimization.CriticalNative;
@@ -54,6 +55,7 @@
public static boolean sCompatibilitySetBitmap = false;
/** @hide */
+ @UnsupportedAppUsage
public long getNativeCanvasWrapper() {
return mNativeCanvasWrapper;
}
@@ -62,6 +64,7 @@
public boolean isRecordingFor(Object o) { return false; }
// may be null
+ @UnsupportedAppUsage
private Bitmap mBitmap;
// optional field set by the caller
@@ -123,6 +126,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public Canvas(long nativeCanvas) {
if (nativeCanvas == 0) {
throw new IllegalStateException();
@@ -141,6 +145,7 @@
* @hide
*/
@Deprecated
+ @UnsupportedAppUsage
protected GL getGL() {
return null;
}
@@ -269,6 +274,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public void setScreenDensity(int density) {
mScreenDensity = density;
}
@@ -1263,6 +1269,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void release() {
mNativeCanvasWrapper = 0;
if (mFinalizer != null) {
@@ -1276,6 +1283,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static void freeCaches() {
nFreeCaches();
}
@@ -1285,6 +1293,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static void freeTextLayoutCaches() {
nFreeTextLayoutCaches();
}
@@ -1591,9 +1600,9 @@
* Draw the specified circle using the specified paint. If radius is <= 0, then nothing will be
* drawn. The circle will be filled or framed based on the Style in the paint.
*
- * @param cx The x-coordinate of the center of the cirle to be drawn
- * @param cy The y-coordinate of the center of the cirle to be drawn
- * @param radius The radius of the cirle to be drawn
+ * @param cx The x-coordinate of the center of the circle to be drawn
+ * @param cy The y-coordinate of the center of the circle to be drawn
+ * @param radius The radius of the circle to be drawn
* @param paint The paint used to draw the circle
*/
public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) {
diff --git a/graphics/java/android/graphics/CanvasProperty.java b/graphics/java/android/graphics/CanvasProperty.java
index ea3886c..1275e08 100644
--- a/graphics/java/android/graphics/CanvasProperty.java
+++ b/graphics/java/android/graphics/CanvasProperty.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import com.android.internal.util.VirtualRefBasePtr;
/**
@@ -26,10 +27,12 @@
private VirtualRefBasePtr mProperty;
+ @UnsupportedAppUsage
public static CanvasProperty<Float> createFloat(float initialValue) {
return new CanvasProperty<Float>(nCreateFloat(initialValue));
}
+ @UnsupportedAppUsage
public static CanvasProperty<Paint> createPaint(Paint initialValue) {
return new CanvasProperty<Paint>(nCreatePaint(initialValue.getNativeInstance()));
}
diff --git a/graphics/java/android/graphics/ColorMatrixColorFilter.java b/graphics/java/android/graphics/ColorMatrixColorFilter.java
index 9201a2e..0f7980c 100644
--- a/graphics/java/android/graphics/ColorMatrixColorFilter.java
+++ b/graphics/java/android/graphics/ColorMatrixColorFilter.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
/**
* A color filter that transforms colors through a 4x5 color matrix. This filter
@@ -26,6 +27,7 @@
* @see ColorMatrix
*/
public class ColorMatrixColorFilter extends ColorFilter {
+ @UnsupportedAppUsage
private final ColorMatrix mMatrix = new ColorMatrix();
/**
@@ -76,6 +78,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorMatrix(@Nullable ColorMatrix matrix) {
discardNativeInstance();
if (matrix == null) {
@@ -104,6 +107,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorMatrixArray(@Nullable float[] array) {
// called '...Array' so that passing null isn't ambiguous
discardNativeInstance();
diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java
index c69eb32..229923c 100644
--- a/graphics/java/android/graphics/FontFamily.java
+++ b/graphics/java/android/graphics/FontFamily.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.graphics.fonts.FontVariationAxis;
import android.text.TextUtils;
@@ -51,16 +52,19 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public long mNativePtr;
// Points native font family builder. Must be zero after freezing this family.
private long mBuilderPtr;
+ @UnsupportedAppUsage
public FontFamily() {
mBuilderPtr = nInitBuilder(null, 0);
mNativeBuilderCleaner = sBuilderRegistry.registerNativeAllocation(this, mBuilderPtr);
}
+ @UnsupportedAppUsage
public FontFamily(@Nullable String[] langs, int variant) {
final String langsString;
if (langs == null || langs.length == 0) {
@@ -80,6 +84,7 @@
* @return boolean returns false if some error happens in native code, e.g. broken font file is
* passed, etc.
*/
+ @UnsupportedAppUsage
public boolean freeze() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen");
@@ -93,6 +98,7 @@
return mNativePtr != 0;
}
+ @UnsupportedAppUsage
public void abortCreation() {
if (mBuilderPtr == 0) {
throw new IllegalStateException("This FontFamily is already frozen or abandoned");
@@ -122,6 +128,7 @@
}
}
+ @UnsupportedAppUsage
public boolean addFontFromBuffer(ByteBuffer font, int ttcIndex, FontVariationAxis[] axes,
int weight, int italic) {
if (mBuilderPtr == 0) {
@@ -147,6 +154,7 @@
* using the OS/2 table in the font.
* @return
*/
+ @UnsupportedAppUsage
public boolean addFontFromAssetManager(AssetManager mgr, String path, int cookie,
boolean isAsset, int ttcIndex, int weight, int isItalic,
FontVariationAxis[] axes) {
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 431d0e0..e3e8380 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontVariationAxis;
import android.text.FontConfig;
import android.util.Xml;
@@ -37,6 +38,7 @@
public class FontListParser {
/* Parse fallback list (no names) */
+ @UnsupportedAppUsage
public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
diff --git a/graphics/java/android/graphics/GraphicBuffer.java b/graphics/java/android/graphics/GraphicBuffer.java
index 53d2177..7408683 100644
--- a/graphics/java/android/graphics/GraphicBuffer.java
+++ b/graphics/java/android/graphics/GraphicBuffer.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -53,6 +54,7 @@
private final int mFormat;
private final int mUsage;
// Note: do not rename, this field is used by native code
+ @UnsupportedAppUsage
private final long mNativeObject;
// These two fields are only used by lock/unlockCanvas()
@@ -84,6 +86,7 @@
/**
* Private use only. See {@link #create(int, int, int, int)}.
*/
+ @UnsupportedAppUsage
private GraphicBuffer(int width, int height, int format, int usage, long nativeObject) {
mWidth = width;
mHeight = height;
@@ -96,6 +99,7 @@
* For SurfaceControl JNI.
* @hide
*/
+ @UnsupportedAppUsage
public static GraphicBuffer createFromExisting(int width, int height,
int format, int usage, long unwrappedNativeObject) {
long nativeObject = nWrapGraphicBuffer(unwrappedNativeObject);
@@ -274,6 +278,7 @@
nWriteGraphicBufferToParcel(mNativeObject, dest);
}
+ @UnsupportedAppUsage
public static final Parcelable.Creator<GraphicBuffer> CREATOR =
new Parcelable.Creator<GraphicBuffer>() {
public GraphicBuffer createFromParcel(Parcel in) {
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 098f100..7bed1ac 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -28,6 +28,7 @@
import android.annotation.Nullable;
import android.annotation.Px;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.annotation.WorkerThread;
import android.content.ContentResolver;
import android.content.res.AssetFileDescriptor;
@@ -1856,6 +1857,7 @@
* Private method called by JNI.
*/
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
private int postProcessAndRelease(@NonNull Canvas canvas) {
try {
return mPostProcessor.onPostProcess(canvas);
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 43fd270..9546a4a 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
public class ImageFormat {
/*
* these constants are chosen to be binary compatible with their previous
@@ -103,6 +105,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static final int Y8 = 0x20203859;
/**
diff --git a/graphics/java/android/graphics/LightingColorFilter.java b/graphics/java/android/graphics/LightingColorFilter.java
index 1578ffb..62a890f 100644
--- a/graphics/java/android/graphics/LightingColorFilter.java
+++ b/graphics/java/android/graphics/LightingColorFilter.java
@@ -22,6 +22,7 @@
package android.graphics;
import android.annotation.ColorInt;
+import android.annotation.UnsupportedAppUsage;
/**
* A color filter that can be used to simulate simple lighting effects.
@@ -72,6 +73,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorMultiply(@ColorInt int mul) {
if (mMul != mul) {
mMul = mul;
@@ -97,6 +99,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setColorAdd(@ColorInt int add) {
if (mAdd != add) {
mAdd = add;
diff --git a/graphics/java/android/graphics/LinearGradient.java b/graphics/java/android/graphics/LinearGradient.java
index 7139efe..7e6fc35 100644
--- a/graphics/java/android/graphics/LinearGradient.java
+++ b/graphics/java/android/graphics/LinearGradient.java
@@ -19,6 +19,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
public class LinearGradient extends Shader {
@@ -31,15 +32,24 @@
*/
private int mType;
+ @UnsupportedAppUsage
private float mX0;
+ @UnsupportedAppUsage
private float mY0;
+ @UnsupportedAppUsage
private float mX1;
+ @UnsupportedAppUsage
private float mY1;
+ @UnsupportedAppUsage
private int[] mColors;
+ @UnsupportedAppUsage
private float[] mPositions;
+ @UnsupportedAppUsage
private int mColor0;
+ @UnsupportedAppUsage
private int mColor1;
+ @UnsupportedAppUsage
private TileMode mTileMode;
/**
diff --git a/graphics/java/android/graphics/Matrix.java b/graphics/java/android/graphics/Matrix.java
index 486070c..f8cb366 100644
--- a/graphics/java/android/graphics/Matrix.java
+++ b/graphics/java/android/graphics/Matrix.java
@@ -21,6 +21,7 @@
import libcore.util.NativeAllocationRegistry;
+import android.annotation.UnsupportedAppUsage;
import java.io.PrintWriter;
/**
@@ -39,6 +40,7 @@
public static final int MPERSP_2 = 8; //!< use with getValues/setValues
/** @hide */
+ @UnsupportedAppUsage
public final static Matrix IDENTITY_MATRIX = new Matrix() {
void oops() {
throw new IllegalStateException("Matrix can not be modified");
@@ -231,6 +233,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public final long native_instance;
/**
diff --git a/graphics/java/android/graphics/Movie.java b/graphics/java/android/graphics/Movie.java
index 83857be..4c953b5 100644
--- a/graphics/java/android/graphics/Movie.java
+++ b/graphics/java/android/graphics/Movie.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import java.io.FileInputStream;
@@ -25,8 +26,10 @@
* @deprecated Prefer {@link android.graphics.drawable.AnimatedImageDrawable}.
*/
public class Movie {
+ @UnsupportedAppUsage
private long mNativeMovie;
+ @UnsupportedAppUsage
private Movie(long nativeMovie) {
if (nativeMovie == 0) {
throw new RuntimeException("native movie creation failed");
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index b6a209f..800247a 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* The NinePatch class permits drawing a bitmap in nine or more sections.
* Essentially, it allows the creation of custom graphics that will scale the
@@ -41,6 +43,7 @@
*/
public static class InsetStruct {
@SuppressWarnings({"UnusedDeclaration"}) // called from JNI
+ @UnsupportedAppUsage
InsetStruct(int opticalLeft, int opticalTop, int opticalRight, int opticalBottom,
int outlineLeft, int outlineTop, int outlineRight, int outlineBottom,
float outlineRadius, int outlineAlpha, float decodeScale) {
@@ -77,6 +80,7 @@
}
}
+ @UnsupportedAppUsage
private final Bitmap mBitmap;
/**
@@ -84,6 +88,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public long mNativeChunk;
private Paint mPaint;
diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java
index 1c85df0..98c990a 100644
--- a/graphics/java/android/graphics/Outline.java
+++ b/graphics/java/android/graphics/Outline.java
@@ -19,6 +19,7 @@
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.drawable.Drawable;
import java.lang.annotation.Retention;
@@ -66,6 +67,7 @@
public Path mPath;
/** @hide */
+ @UnsupportedAppUsage
public final Rect mRect = new Rect();
/** @hide */
public float mRadius = RADIUS_UNDEFINED;
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 42dac38..9dab536 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -19,6 +19,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontVariationAxis;
import android.os.LocaleList;
import android.text.GraphicsOperations;
@@ -44,6 +45,7 @@
*/
public class Paint {
+ @UnsupportedAppUsage
private long mNativePaint;
private long mNativeShader;
private long mNativeColorFilter;
@@ -61,6 +63,7 @@
private MaskFilter mMaskFilter;
private PathEffect mPathEffect;
private Shader mShader;
+ @UnsupportedAppUsage
private Typeface mTypeface;
private Xfermode mXfermode;
@@ -618,6 +621,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public void setCompatibilityScaling(float factor) {
if (factor == 1.0) {
mHasCompatScaling = false;
@@ -635,6 +639,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public long getNativeInstance() {
long newNativeShader = mShader == null ? 0 : mShader.getNativeInstance();
if (newNativeShader != mNativeShader) {
@@ -1718,6 +1723,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void setHyphenEdit(int hyphen) {
nSetHyphenEdit(mNativePaint, hyphen);
}
@@ -2261,6 +2267,7 @@
* @see #getTextRunAdvances(String, int, int, int, int, boolean, float[], int)
* @hide
*/
+ @UnsupportedAppUsage
public float getTextRunAdvances(char[] chars, int index, int count,
int contextIndex, int contextCount, boolean isRtl, float[] advances,
int advancesIndex) {
@@ -2451,6 +2458,7 @@
* @return the offset of the next position, or -1
* @hide
*/
+ @UnsupportedAppUsage
public int getTextRunCursor(char[] text, int contextStart, int contextLength,
int dir, int offset, int cursorOpt) {
int contextEnd = contextStart + contextLength;
diff --git a/graphics/java/android/graphics/Path.java b/graphics/java/android/graphics/Path.java
index 1652f64..405ab0b 100644
--- a/graphics/java/android/graphics/Path.java
+++ b/graphics/java/android/graphics/Path.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.UnsupportedAppUsage;
import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;
@@ -46,10 +47,12 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public boolean isSimplePath = true;
/**
* @hide
*/
+ @UnsupportedAppUsage
public Region rects;
private Direction mLastDirection = null;
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index f2d0227..f7acb11 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import java.io.InputStream;
import java.io.OutputStream;
@@ -32,6 +33,7 @@
*/
public class Picture {
private PictureCanvas mRecordingCanvas;
+ @UnsupportedAppUsage
private long mNativePicture;
private boolean mRequiresHwAcceleration;
diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index d7d3049..fba5043 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* <p>This class contains the list of alpha compositing and blending modes
* that can be passed to {@link PorterDuffXfermode}, a specialized implementation
@@ -364,6 +366,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public final int nativeInt;
}
diff --git a/graphics/java/android/graphics/PorterDuffColorFilter.java b/graphics/java/android/graphics/PorterDuffColorFilter.java
index 88a6322..6665220 100644
--- a/graphics/java/android/graphics/PorterDuffColorFilter.java
+++ b/graphics/java/android/graphics/PorterDuffColorFilter.java
@@ -18,6 +18,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
/**
* A color filter that can be used to tint the source pixels using a single
@@ -50,6 +51,7 @@
* @hide
*/
@ColorInt
+ @UnsupportedAppUsage
public int getColor() {
return mColor;
}
@@ -62,6 +64,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public PorterDuff.Mode getMode() {
return mMode;
}
diff --git a/graphics/java/android/graphics/RadialGradient.java b/graphics/java/android/graphics/RadialGradient.java
index f4b1191..41d2628 100644
--- a/graphics/java/android/graphics/RadialGradient.java
+++ b/graphics/java/android/graphics/RadialGradient.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.ColorInt;
+import android.annotation.UnsupportedAppUsage;
public class RadialGradient extends Shader {
@@ -31,14 +32,22 @@
*/
private int mType;
+ @UnsupportedAppUsage
private float mX;
+ @UnsupportedAppUsage
private float mY;
+ @UnsupportedAppUsage
private float mRadius;
+ @UnsupportedAppUsage
private int[] mColors;
+ @UnsupportedAppUsage
private float[] mPositions;
+ @UnsupportedAppUsage
private int mCenterColor;
+ @UnsupportedAppUsage
private int mEdgeColor;
+ @UnsupportedAppUsage
private TileMode mTileMode;
/**
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 56a6820..4fec33f 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -19,6 +19,7 @@
import android.annotation.CheckResult;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -206,6 +207,7 @@
* Print short representation to given writer.
* @hide
*/
+ @UnsupportedAppUsage
public void printShortString(@NonNull PrintWriter pw) {
pw.print('['); pw.print(left); pw.print(',');
pw.print(top); pw.print("]["); pw.print(right);
@@ -694,6 +696,7 @@
* Scales up the rect by the given scale.
* @hide
*/
+ @UnsupportedAppUsage
public void scale(float scale) {
if (scale != 1.0f) {
left = (int) (left * scale + 0.5f);
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index b27fadd..29d9367 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pools.SynchronizedPool;
@@ -31,6 +32,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public long mNativeRegion;
// the native values for these must match up with the enum in SkRegion.h
@@ -49,6 +51,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public final int nativeInt;
}
@@ -239,6 +242,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void scale(float scale) {
scale(scale, null);
}
@@ -333,6 +337,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public void recycle() {
setEmpty();
sPool.release(this);
@@ -406,6 +411,7 @@
/* add dummy parameter so constructor can be called from jni without
triggering 'not cloneable' exception */
+ @UnsupportedAppUsage
private Region(long ni, int dummy) {
this(ni);
}
diff --git a/graphics/java/android/graphics/Shader.java b/graphics/java/android/graphics/Shader.java
index 40288f5..40bcc9e 100644
--- a/graphics/java/android/graphics/Shader.java
+++ b/graphics/java/android/graphics/Shader.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import libcore.util.NativeAllocationRegistry;
@@ -72,6 +73,7 @@
TileMode(int nativeInt) {
this.nativeInt = nativeInt;
}
+ @UnsupportedAppUsage
final int nativeInt;
}
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 1eebd26..99f440d 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -17,6 +17,7 @@
package android.graphics;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -68,13 +69,17 @@
*/
public class SurfaceTexture {
private final Looper mCreatorLooper;
+ @UnsupportedAppUsage
private Handler mOnFrameAvailableHandler;
/**
* These fields are used by native code, do not access or modify.
*/
+ @UnsupportedAppUsage
private long mSurfaceTexture;
+ @UnsupportedAppUsage
private long mProducer;
+ @UnsupportedAppUsage
private long mFrameAvailableListener;
private boolean mIsSingleBuffered;
@@ -378,6 +383,7 @@
* This method is invoked from native code only.
*/
@SuppressWarnings({"UnusedDeclaration"})
+ @UnsupportedAppUsage
private static void postEventFromNative(WeakReference<SurfaceTexture> weakSelf) {
SurfaceTexture st = weakSelf.get();
if (st != null) {
@@ -405,6 +411,7 @@
private native void nativeSetDefaultBufferSize(int width, int height);
private native void nativeUpdateTexImage();
private native void nativeReleaseTexImage();
+ @UnsupportedAppUsage
private native int nativeDetachFromGLContext();
private native int nativeAttachToGLContext(int texName);
private native void nativeRelease();
diff --git a/graphics/java/android/graphics/SweepGradient.java b/graphics/java/android/graphics/SweepGradient.java
index b6b80b4..f944d85 100644
--- a/graphics/java/android/graphics/SweepGradient.java
+++ b/graphics/java/android/graphics/SweepGradient.java
@@ -19,6 +19,7 @@
import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
public class SweepGradient extends Shader {
@@ -31,11 +32,17 @@
*/
private int mType;
+ @UnsupportedAppUsage
private float mCx;
+ @UnsupportedAppUsage
private float mCy;
+ @UnsupportedAppUsage
private int[] mColors;
+ @UnsupportedAppUsage
private float[] mPositions;
+ @UnsupportedAppUsage
private int mColor0;
+ @UnsupportedAppUsage
private int mColor1;
/**
diff --git a/graphics/java/android/graphics/TableMaskFilter.java b/graphics/java/android/graphics/TableMaskFilter.java
index d0c1438..d81c491 100644
--- a/graphics/java/android/graphics/TableMaskFilter.java
+++ b/graphics/java/android/graphics/TableMaskFilter.java
@@ -16,6 +16,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* @hide
*/
@@ -32,6 +34,7 @@
native_instance = ni;
}
+ @UnsupportedAppUsage
public static TableMaskFilter CreateClipTable(int min, int max) {
return new TableMaskFilter(nativeNewClip(min, max));
}
diff --git a/graphics/java/android/graphics/TemporaryBuffer.java b/graphics/java/android/graphics/TemporaryBuffer.java
index 36a2275..0ae2c70 100644
--- a/graphics/java/android/graphics/TemporaryBuffer.java
+++ b/graphics/java/android/graphics/TemporaryBuffer.java
@@ -16,12 +16,14 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
import com.android.internal.util.ArrayUtils;
/**
* @hide
*/
public class TemporaryBuffer {
+ @UnsupportedAppUsage
public static char[] obtain(int len) {
char[] buf;
@@ -37,6 +39,7 @@
return buf;
}
+ @UnsupportedAppUsage
public static void recycle(char[] temp) {
if (temp.length > 1000) return;
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 18dd97f..522d7a5 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -25,6 +25,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.graphics.fonts.FontVariationAxis;
import android.net.Uri;
@@ -93,6 +94,7 @@
/** The NORMAL style of the default monospace typeface. */
public static final Typeface MONOSPACE;
+ @UnsupportedAppUsage
static Typeface[] sDefaults;
/**
@@ -119,12 +121,15 @@
private static final Object sDynamicCacheLock = new Object();
static Typeface sDefaultTypeface;
+ @UnsupportedAppUsage
static final Map<String, Typeface> sSystemFontMap;
+ @UnsupportedAppUsage
static final Map<String, FontFamily[]> sSystemFallbackMap;
/**
* @hide
*/
+ @UnsupportedAppUsage
public long native_instance;
/** @hide */
@@ -139,6 +144,7 @@
public static final int BOLD_ITALIC = 3;
/** @hide */ public static final int STYLE_MASK = 0x03;
+ @UnsupportedAppUsage
private @Style int mStyle = 0;
/**
@@ -162,6 +168,7 @@
private int[] mSupportedAxes;
private static final int[] EMPTY_AXES = {};
+ @UnsupportedAppUsage
private static void setDefault(Typeface t) {
sDefaultTypeface = t;
nativeSetDefault(t.native_instance);
@@ -891,6 +898,7 @@
*
* @param families array of font families
*/
+ @UnsupportedAppUsage
private static Typeface createFromFamilies(FontFamily[] families) {
long[] ptrArray = new long[families.length];
for (int i = 0; i < families.length; i++) {
@@ -904,6 +912,7 @@
* This method is used by supportlib-v27.
* TODO: Remove private API use in supportlib: http://b/72665240
*/
+ @UnsupportedAppUsage
private static Typeface createFromFamiliesWithDefault(FontFamily[] families, int weight,
int italic) {
return createFromFamiliesWithDefault(families, DEFAULT_FAMILY, weight, italic);
@@ -922,6 +931,7 @@
* closest to the regular weight and upright font is used.
* @param families array of font families
*/
+ @UnsupportedAppUsage
private static Typeface createFromFamiliesWithDefault(FontFamily[] families,
String fallbackName, int weight, int italic) {
FontFamily[] fallback = sSystemFallbackMap.get(fallbackName);
@@ -939,6 +949,7 @@
}
// don't allow clients to call this directly
+ @UnsupportedAppUsage
private Typeface(long ni) {
if (ni == 0) {
throw new RuntimeException("native typeface cannot be made");
@@ -1197,7 +1208,9 @@
// TODO: clean up: change List<FontVariationAxis> to FontVariationAxis[]
private static native long nativeCreateFromTypefaceWithVariation(
long native_instance, List<FontVariationAxis> axes);
+ @UnsupportedAppUsage
private static native long nativeCreateWeightAlias(long native_instance, int weight);
+ @UnsupportedAppUsage
private static native long nativeCreateFromArray(long[] familyArray, int weight, int italic);
private static native int[] nativeGetSupportedAxes(long native_instance);
diff --git a/graphics/java/android/graphics/Xfermode.java b/graphics/java/android/graphics/Xfermode.java
index a5da5d0..6f4adfd 100644
--- a/graphics/java/android/graphics/Xfermode.java
+++ b/graphics/java/android/graphics/Xfermode.java
@@ -21,6 +21,8 @@
package android.graphics;
+import android.annotation.UnsupportedAppUsage;
+
/**
* Xfermode is the base class for objects that are called to implement custom
* "transfer-modes" in the drawing pipeline. The static function Create(Modes)
@@ -30,5 +32,6 @@
*/
public class Xfermode {
static final int DEFAULT = PorterDuff.Mode.SRC_OVER.nativeInt;
+ @UnsupportedAppUsage
int porterDuffMode = DEFAULT;
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 4f467d9..3aaec31 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -19,6 +19,7 @@
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -562,6 +563,7 @@
* callback, so no need to post.
*/
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
private void onAnimationEnd() {
if (mAnimationCallbacks != null) {
for (Animatable2.AnimationCallback callback : mAnimationCallbacks) {
diff --git a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
index d714ca8..b29fd4d 100644
--- a/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedRotateDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.content.res.Resources;
@@ -202,11 +203,13 @@
R.styleable.AnimatedRotateDrawable_frameDuration, state.mFrameDuration));
}
+ @UnsupportedAppUsage
public void setFramesCount(int framesCount) {
mState.mFramesCount = framesCount;
mIncrement = 360.0f / mState.mFramesCount;
}
+ @UnsupportedAppUsage
public void setFramesDuration(int framesDuration) {
mState.mFrameDuration = framesDuration;
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
index 3ed6a78..00380c5 100644
--- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java
@@ -20,6 +20,7 @@
import android.animation.TimeInterpolator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -66,6 +67,7 @@
private static final String ELEMENT_TRANSITION = "transition";
private static final String ELEMENT_ITEM = "item";
+ @UnsupportedAppUsage
private AnimatedStateListState mState;
/** The currently running transition, if any. */
@@ -558,7 +560,9 @@
int[] mAnimThemeAttrs;
+ @UnsupportedAppUsage
LongSparseLongArray mTransitions;
+ @UnsupportedAppUsage
SparseIntArray mStateIds;
AnimatedStateListState(@Nullable AnimatedStateListState orig,
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 8e9862c..76f2cfb 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -25,6 +25,7 @@
import android.animation.ValueAnimator;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.app.ActivityThread;
import android.app.Application;
import android.content.pm.ActivityInfo.Config;
@@ -305,6 +306,7 @@
private static final boolean DBG_ANIMATION_VECTOR_DRAWABLE = false;
/** Local, mutable animator set. */
+ @UnsupportedAppUsage
private VectorDrawableAnimator mAnimatorSet;
/**
@@ -313,6 +315,7 @@
*/
private Resources mRes;
+ @UnsupportedAppUsage
private AnimatedVectorDrawableState mAnimatedVectorState;
/** The animator set that is parsed from the xml. */
@@ -641,6 +644,7 @@
* Force to animate on UI thread.
* @hide
*/
+ @UnsupportedAppUsage
public void forceAnimationOnUI() {
if (mAnimatorSet instanceof VectorDrawableAnimatorRT) {
VectorDrawableAnimatorRT animator = (VectorDrawableAnimatorRT) mAnimatorSet;
@@ -1771,6 +1775,7 @@
}
// onFinished: should be called from native
+ @UnsupportedAppUsage
private static void callOnFinished(VectorDrawableAnimatorRT set, int id) {
set.onAnimationEnd(id);
}
diff --git a/graphics/java/android/graphics/drawable/AnimationDrawable.java b/graphics/java/android/graphics/drawable/AnimationDrawable.java
index 0fd1741..57764c2 100644
--- a/graphics/java/android/graphics/drawable/AnimationDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimationDrawable.java
@@ -24,6 +24,7 @@
import org.xmlpull.v1.XmlPullParserException;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
@@ -88,6 +89,7 @@
private AnimationState mAnimationState;
/** The current frame, ranging from 0 to {@link #mAnimationState#getChildCount() - 1} */
+ @UnsupportedAppUsage
private int mCurFrame = 0;
/** Whether the drawable has an animation callback posted. */
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 99bed60..9761901 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -17,6 +17,7 @@
package android.graphics.drawable;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -87,9 +88,11 @@
private final Rect mDstRect = new Rect(); // #updateDstRectAndInsetsIfDirty() sets this
+ @UnsupportedAppUsage
private BitmapState mBitmapState;
private PorterDuffColorFilter mTintFilter;
+ @UnsupportedAppUsage
private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
private boolean mDstRectAndInsetsDirty = true;
@@ -237,6 +240,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public void setBitmap(Bitmap bitmap) {
if (mBitmapState.mBitmap != bitmap) {
mBitmapState.mBitmap = bitmap;
@@ -692,6 +696,7 @@
/**
* @hide only needed by a hack within ProgressBar
*/
+ @UnsupportedAppUsage
public ColorStateList getTint() {
return mBitmapState.mTint;
}
@@ -699,6 +704,7 @@
/**
* @hide only needed by a hack within ProgressBar
*/
+ @UnsupportedAppUsage
public Mode getTintMode() {
return mBitmapState.mTintMode;
}
diff --git a/graphics/java/android/graphics/drawable/ClipDrawable.java b/graphics/java/android/graphics/drawable/ClipDrawable.java
index d925b6b..31fdb02 100644
--- a/graphics/java/android/graphics/drawable/ClipDrawable.java
+++ b/graphics/java/android/graphics/drawable/ClipDrawable.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
@@ -58,6 +59,7 @@
private final Rect mTmpRect = new Rect();
+ @UnsupportedAppUsage
private ClipState mState;
ClipDrawable() {
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index a601d6d..18b41fa 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -52,6 +53,7 @@
* @attr ref android.R.styleable#ColorDrawable_color
*/
public class ColorDrawable extends Drawable {
+ @UnsupportedAppUsage
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
@@ -336,6 +338,7 @@
int[] mThemeAttrs;
int mBaseColor; // base color, independent of setAlpha()
@ViewDebug.ExportedProperty
+ @UnsupportedAppUsage
int mUseColor; // basecolor modulated by setAlpha()
@Config int mChangingConfigurations;
ColorStateList mTint = null;
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 986d0c1..e1f7263 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -22,6 +22,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -186,6 +187,7 @@
private int mLevel = 0;
private @Config int mChangingConfigurations = 0;
private Rect mBounds = ZERO_BOUNDS_RECT; // lazily becomes a new Rect()
+ @UnsupportedAppUsage
private WeakReference<Callback> mCallback = null;
private boolean mVisible = true;
@@ -204,6 +206,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
protected int mSrcDensityOverride = 0;
/**
@@ -714,6 +717,7 @@
*
* @hide magic!
*/
+ @UnsupportedAppUsage
public boolean isProjected() {
return false;
}
@@ -1389,6 +1393,7 @@
* @throws XmlPullParserException
* @throws IOException
*/
+ @UnsupportedAppUsage
void inflateWithAttributes(@NonNull @SuppressWarnings("unused") Resources r,
@NonNull @SuppressWarnings("unused") XmlPullParser parser, @NonNull TypedArray attrs,
@AttrRes int visibleAttr) throws XmlPullParserException, IOException {
@@ -1508,6 +1513,7 @@
* Ensures the tint filter is consistent with the current tint color and
* mode.
*/
+ @UnsupportedAppUsage
@Nullable PorterDuffColorFilter updateTintFilter(@Nullable PorterDuffColorFilter tintFilter,
@Nullable ColorStateList tint, @Nullable PorterDuff.Mode tintMode) {
if (tint == null || tintMode == null) {
@@ -1613,6 +1619,7 @@
*
* @hide
*/
+ @UnsupportedAppUsage
public static PorterDuff.Mode parseTintMode(int value, Mode defaultMode) {
switch (value) {
case 3: return Mode.SRC_OVER;
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index e7b383a..10f6fae 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -17,6 +17,7 @@
package android.graphics.drawable;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -54,9 +55,11 @@
* to improve the quality at negligible cost.
*/
private static final boolean DEFAULT_DITHER = true;
+ @UnsupportedAppUsage
private DrawableContainerState mDrawableContainerState;
private Rect mHotspotBounds;
private Drawable mCurrDrawable;
+ @UnsupportedAppUsage
private Drawable mLastDrawable;
private int mAlpha = 0xFF;
@@ -686,11 +689,13 @@
@Config int mChildrenChangingConfigurations;
SparseArray<ConstantState> mDrawableFutures;
+ @UnsupportedAppUsage
Drawable[] mDrawables;
int mNumChildren;
boolean mVariablePadding = false;
boolean mCheckedPadding;
+ @UnsupportedAppUsage
Rect mConstantPadding;
boolean mConstantSize = false;
@@ -720,6 +725,7 @@
boolean mAutoMirrored;
ColorFilter mColorFilter;
+ @UnsupportedAppUsage
boolean mHasColorFilter;
ColorStateList mTintList;
@@ -730,6 +736,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
protected DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
Resources res) {
mOwner = owner;
diff --git a/graphics/java/android/graphics/drawable/DrawableInflater.java b/graphics/java/android/graphics/drawable/DrawableInflater.java
index 0ee9071..bad3791 100644
--- a/graphics/java/android/graphics/drawable/DrawableInflater.java
+++ b/graphics/java/android/graphics/drawable/DrawableInflater.java
@@ -22,6 +22,7 @@
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
@@ -49,6 +50,7 @@
new HashMap<>();
private final Resources mRes;
+ @UnsupportedAppUsage
private final ClassLoader mClassLoader;
/**
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index a907ca5..4ee45bf 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -46,6 +47,7 @@
* Drawable container with only one child element.
*/
public abstract class DrawableWrapper extends Drawable implements Drawable.Callback {
+ @UnsupportedAppUsage
private DrawableWrapperState mState;
private Drawable mDrawable;
private boolean mMutated;
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 5629389..8740234 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -20,6 +20,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -155,10 +156,14 @@
private static final float DEFAULT_INNER_RADIUS_RATIO = 3.0f;
private static final float DEFAULT_THICKNESS_RATIO = 9.0f;
+ @UnsupportedAppUsage
private GradientState mGradientState;
+ @UnsupportedAppUsage
private final Paint mFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ @UnsupportedAppUsage
private Rect mPadding;
+ @UnsupportedAppUsage
private Paint mStrokePaint; // optional, set by the caller
private ColorFilter mColorFilter; // optional, set by the caller
private PorterDuffColorFilter mTintFilter;
@@ -1792,27 +1797,46 @@
final static class GradientState extends ConstantState {
public @Config int mChangingConfigurations;
+ @UnsupportedAppUsage
public @Shape int mShape = RECTANGLE;
+ @UnsupportedAppUsage
public @GradientType int mGradient = LINEAR_GRADIENT;
+ @UnsupportedAppUsage
public int mAngle = 0;
+ @UnsupportedAppUsage
public Orientation mOrientation;
+ @UnsupportedAppUsage
public ColorStateList mSolidColors;
public ColorStateList mStrokeColors;
+ @UnsupportedAppUsage
public @ColorInt int[] mGradientColors;
public @ColorInt int[] mTempColors; // no need to copy
public float[] mTempPositions; // no need to copy
+ @UnsupportedAppUsage
public float[] mPositions;
+ @UnsupportedAppUsage
public int mStrokeWidth = -1; // if >= 0 use stroking.
+ @UnsupportedAppUsage
public float mStrokeDashWidth = 0.0f;
+ @UnsupportedAppUsage
public float mStrokeDashGap = 0.0f;
+ @UnsupportedAppUsage
public float mRadius = 0.0f; // use this if mRadiusArray is null
+ @UnsupportedAppUsage
public float[] mRadiusArray = null;
+ @UnsupportedAppUsage
public Rect mPadding = null;
+ @UnsupportedAppUsage
public int mWidth = -1;
+ @UnsupportedAppUsage
public int mHeight = -1;
+ @UnsupportedAppUsage
public float mInnerRadiusRatio = DEFAULT_INNER_RADIUS_RATIO;
+ @UnsupportedAppUsage
public float mThicknessRatio = DEFAULT_THICKNESS_RATIO;
+ @UnsupportedAppUsage
public int mInnerRadius = -1;
+ @UnsupportedAppUsage
public int mThickness = -1;
public boolean mDither = false;
public Insets mOpticalInsets = Insets.NONE;
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 361fe0b..accc081 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -21,6 +21,7 @@
import android.annotation.IdRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@@ -99,6 +100,7 @@
private static final int VERSION_STREAM_SERIALIZER = 1;
+ @UnsupportedAppUsage
private final int mType;
private ColorStateList mTintList;
@@ -115,6 +117,7 @@
// TYPE_RESOURCE: package name
// TYPE_URI: uri string
+ @UnsupportedAppUsage
private String mString1;
// TYPE_RESOURCE: resId
@@ -139,6 +142,7 @@
* @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon.
* @hide
*/
+ @UnsupportedAppUsage
public Bitmap getBitmap() {
if (mType != TYPE_BITMAP && mType != TYPE_ADAPTIVE_BITMAP) {
throw new IllegalStateException("called getBitmap() on " + this);
@@ -154,6 +158,7 @@
* @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon.
* @hide
*/
+ @UnsupportedAppUsage
public int getDataLength() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataLength() on " + this);
@@ -168,6 +173,7 @@
* valid compressed bitmap data is found.
* @hide
*/
+ @UnsupportedAppUsage
public int getDataOffset() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataOffset() on " + this);
@@ -182,6 +188,7 @@
* bitmap data.
* @hide
*/
+ @UnsupportedAppUsage
public byte[] getDataBytes() {
if (mType != TYPE_DATA) {
throw new IllegalStateException("called getDataBytes() on " + this);
@@ -195,6 +202,7 @@
* @return The {@link android.content.res.Resources} for this {@link #TYPE_RESOURCE} Icon.
* @hide
*/
+ @UnsupportedAppUsage
public Resources getResources() {
if (mType != TYPE_RESOURCE) {
throw new IllegalStateException("called getResources() on " + this);
@@ -560,6 +568,7 @@
* Version of createWithResource that takes Resources. Do not use.
* @hide
*/
+ @UnsupportedAppUsage
public static Icon createWithResource(Resources res, @DrawableRes int resId) {
if (res == null) {
throw new IllegalArgumentException("Resource must not be null.");
@@ -692,6 +701,7 @@
}
/** @hide */
+ @UnsupportedAppUsage
public boolean hasTint() {
return (mTintList != null) || (mTintMode != DEFAULT_TINT_MODE);
}
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index ade4294..bc8a4cb 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -57,6 +58,7 @@
private final Rect mTmpRect = new Rect();
private final Rect mTmpInsetRect = new Rect();
+ @UnsupportedAppUsage
private InsetState mState;
/**
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 4725c2c..b4392c8 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -93,6 +94,7 @@
public static final int INSET_UNDEFINED = Integer.MIN_VALUE;
@NonNull
+ @UnsupportedAppUsage
LayerState mLayerState;
private int[] mPaddingL;
@@ -428,6 +430,7 @@
* @param layer The layer to add.
* @return The index of the layer.
*/
+ @UnsupportedAppUsage
int addLayer(@NonNull ChildDrawable layer) {
final LayerState st = mLayerState;
final int N = st.mChildren != null ? st.mChildren.length : 0;
@@ -1739,6 +1742,7 @@
/**
* Ensures the child padding caches are large enough.
*/
+ @UnsupportedAppUsage
void ensurePadding() {
final int N = mLayerState.mNumChildren;
if (mPaddingL != null && mPaddingL.length >= N) {
@@ -1820,6 +1824,7 @@
}
static class ChildDrawable {
+ @UnsupportedAppUsage
public Drawable mDrawable;
public int[] mThemeAttrs;
public int mDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -1922,6 +1927,7 @@
private int[] mThemeAttrs;
int mNumChildren;
+ @UnsupportedAppUsage
ChildDrawable[] mChildren;
int mDensity;
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index 7f23cea..b534771 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -70,6 +71,7 @@
/** Temporary rect used for density scaling. */
private Rect mTempRect;
+ @UnsupportedAppUsage
private NinePatchState mNinePatchState;
private PorterDuffColorFilter mTintFilter;
private Rect mPadding;
@@ -588,6 +590,7 @@
@Config int mChangingConfigurations;
// Values loaded during inflation.
+ @UnsupportedAppUsage
NinePatch mNinePatch = null;
ColorStateList mTint = null;
Mode mTintMode = DEFAULT_TINT_MODE;
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 266a6ac..1540cc2 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
@@ -120,6 +121,7 @@
private final Rect mDirtyBounds = new Rect();
/** Mirrors mLayerState with some extra information. */
+ @UnsupportedAppUsage
private RippleState mState;
/** The masking layer, e.g. the layer with id R.id.mask. */
@@ -157,6 +159,7 @@
private Paint mRipplePaint;
/** Target density of the display into which ripples are drawn. */
+ @UnsupportedAppUsage
private int mDensity;
/** Whether bounds are being overridden. */
@@ -857,6 +860,7 @@
mMask.draw(canvas);
}
+ @UnsupportedAppUsage
Paint getRipplePaint() {
if (mRipplePaint == null) {
mRipplePaint = new Paint();
@@ -945,6 +949,7 @@
* @param forceSoftware true if RenderThread animations should be disabled, false otherwise
* @hide
*/
+ @UnsupportedAppUsage
public void setForceSoftware(boolean forceSoftware) {
mForceSoftware = forceSoftware;
}
@@ -975,6 +980,7 @@
static class RippleState extends LayerState {
int[] mTouchThemeAttrs;
+ @UnsupportedAppUsage
ColorStateList mColor = ColorStateList.valueOf(Color.MAGENTA);
int mMaxRadius = RADIUS_AUTO;
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index c0dfe77..db5f082 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.content.res.Resources;
@@ -54,6 +55,7 @@
public class RotateDrawable extends DrawableWrapper {
private static final int MAX_LEVEL = 10000;
+ @UnsupportedAppUsage
private RotateState mState;
/**
diff --git a/graphics/java/android/graphics/drawable/ScaleDrawable.java b/graphics/java/android/graphics/drawable/ScaleDrawable.java
index 51e143b..91ed061 100644
--- a/graphics/java/android/graphics/drawable/ScaleDrawable.java
+++ b/graphics/java/android/graphics/drawable/ScaleDrawable.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -66,6 +67,7 @@
private final Rect mTmpRect = new Rect();
+ @UnsupportedAppUsage
private ScaleState mState;
ScaleDrawable() {
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 67c3412..8de8f81 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
@@ -63,6 +64,7 @@
private static final boolean DEBUG = false;
+ @UnsupportedAppUsage
private StateListState mStateListState;
private boolean mMutated;
@@ -129,6 +131,7 @@
/**
* Updates the constant state from the values in the typed array.
*/
+ @UnsupportedAppUsage
private void updateStateFromTypedArray(TypedArray a) {
final StateListState state = mStateListState;
@@ -206,6 +209,7 @@
* @param attrs The attribute set.
* @return An array of state_ attributes.
*/
+ @UnsupportedAppUsage
int[] extractStateSet(AttributeSet attrs) {
int j = 0;
final int numAttrs = attrs.getAttributeCount();
@@ -329,6 +333,7 @@
mStateSets = stateSets;
}
+ @UnsupportedAppUsage
int addStateSet(int[] stateSet, Drawable drawable) {
final int pos = addChild(drawable);
mStateSets[pos] = stateSet;
diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java
index 3dfd680..276f366 100644
--- a/graphics/java/android/graphics/drawable/TransitionDrawable.java
+++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java
@@ -16,6 +16,7 @@
package android.graphics.drawable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -65,10 +66,13 @@
private boolean mReverse;
private long mStartTimeMillis;
private int mFrom;
+ @UnsupportedAppUsage
private int mTo;
private int mDuration;
private int mOriginalDuration;
+ @UnsupportedAppUsage
private int mAlpha = 0;
+ @UnsupportedAppUsage
private boolean mCrossFade;
/**
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index b5bd97f..040601c 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -16,6 +16,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.ComplexColor;
@@ -321,6 +322,7 @@
private VectorDrawableState mVectorState;
+ @UnsupportedAppUsage
private PorterDuffColorFilter mTintFilter;
private ColorFilter mColorFilter;
@@ -389,6 +391,7 @@
mMutated = false;
}
+ @UnsupportedAppUsage
Object getTargetByName(String name) {
return mVectorState.mVGTargetsMap.get(name);
}
@@ -867,6 +870,7 @@
return super.getChangingConfigurations() | mVectorState.getChangingConfigurations();
}
+ @UnsupportedAppUsage
void setAllowCaching(boolean allowCaching) {
nSetAllowCaching(mVectorState.getNativeRenderer(), allowCaching);
}
@@ -1498,6 +1502,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setRotation(float rotation) {
if (isTreeValid()) {
nSetRotation(mNativePtr, rotation);
@@ -1510,6 +1515,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setPivotX(float pivotX) {
if (isTreeValid()) {
nSetPivotX(mNativePtr, pivotX);
@@ -1522,6 +1528,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setPivotY(float pivotY) {
if (isTreeValid()) {
nSetPivotY(mNativePtr, pivotY);
@@ -1558,6 +1565,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setTranslateX(float translateX) {
if (isTreeValid()) {
nSetTranslateX(mNativePtr, translateX);
@@ -1570,6 +1578,7 @@
}
@SuppressWarnings("unused")
+ @UnsupportedAppUsage
public void setTranslateY(float translateY) {
if (isTreeValid()) {
nSetTranslateY(mNativePtr, translateY);
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
new file mode 100644
index 0000000..9da61db9
--- /dev/null
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2018 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.graphics.fonts;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.util.TypedValue;
+
+import com.android.internal.util.Preconditions;
+
+import dalvik.annotation.optimization.CriticalNative;
+
+import libcore.util.NativeAllocationRegistry;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+/**
+ * A font class can be used for creating FontFamily.
+ */
+public class Font {
+ private static final String TAG = "Font";
+
+ private static final int NOT_SPECIFIED = -1;
+ private static final int STYLE_ITALIC = 1;
+ private static final int STYLE_NORMAL = 0;
+
+ /**
+ * A font weight value for the thin weight
+ */
+ public static final int FONT_WEIGHT_THIN = 100;
+
+ /**
+ * A font weight value for the extra-light weight
+ */
+ public static final int FONT_WEIGHT_EXTRA_LIGHT = 200;
+
+ /**
+ * A font weight value for the light weight
+ */
+ public static final int FONT_WEIGHT_LIGHT = 300;
+
+ /**
+ * A font weight value for the normal weight
+ */
+ public static final int FONT_WEIGHT_NORMAL = 400;
+
+ /**
+ * A font weight value for the medium weight
+ */
+ public static final int FONT_WEIGHT_MEDIUM = 500;
+
+ /**
+ * A font weight value for the semi-bold weight
+ */
+ public static final int FONT_WEIGHT_SEMI_BOLD = 600;
+
+ /**
+ * A font weight value for the bold weight.
+ */
+ public static final int FONT_WEIGHT_BOLD = 700;
+
+ /**
+ * A font weight value for the extra-bold weight
+ */
+ public static final int FONT_WEIGHT_EXTRA_BOLD = 800;
+
+ /**
+ * A font weight value for the black weight
+ */
+ public static final int FONT_WEIGHT_BLACK = 900;
+
+ /**
+ * A builder class for creating new Font.
+ */
+ public static class Builder {
+ private static final NativeAllocationRegistry sAssetByteBufferRegistroy =
+ new NativeAllocationRegistry(ByteBuffer.class.getClassLoader(),
+ nGetReleaseNativeAssetFunc(), 64);
+
+ private static final NativeAllocationRegistry sFontRegistory =
+ new NativeAllocationRegistry(Font.class.getClassLoader(),
+ nGetReleaseNativeFont(), 64);
+
+ private @Nullable ByteBuffer mBuffer;
+ private @IntRange(from = -1, to = 1000) int mWeight = NOT_SPECIFIED;
+ private @IntRange(from = -1, to = 1) int mItalic = NOT_SPECIFIED;
+ private @IntRange(from = 0) int mTtcIndex = 0;
+ private @Nullable FontVariationAxis[] mAxes = null;
+
+ /**
+ * Constructs a builder with a byte buffer.
+ *
+ * Note that only direct buffer can be used as the source of font data.
+ *
+ * @see ByteBuffer#allocateDirect(int)
+ * @param buffer a byte buffer of a font data
+ */
+ public Builder(@NonNull ByteBuffer buffer) {
+ Preconditions.checkNotNull(buffer, "buffer can not be null");
+ if (!buffer.isDirect()) {
+ throw new IllegalArgumentException(
+ "Only direct buffer can be used as the source of font data.");
+ }
+ mBuffer = buffer;
+ }
+
+ /**
+ * Constructs a builder with a file path.
+ *
+ * @param path a file path to the font file
+ */
+ public Builder(@NonNull File path) throws IOException {
+ Preconditions.checkNotNull(path, "path can not be null");
+ try (FileInputStream fis = new FileInputStream(path)) {
+ final FileChannel fc = fis.getChannel();
+ mBuffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
+ }
+ }
+
+ /**
+ * Constructs a builder with a file descriptor.
+ *
+ * @param fd a file descriptor
+ */
+ public Builder(@NonNull FileDescriptor fd) throws IOException {
+ this(fd, 0, -1);
+ }
+
+ /**
+ * Constructs a builder with a file descriptor.
+ *
+ * @param fd a file descriptor
+ * @param offset an offset to of the font data in the file
+ * @param size a size of the font data. If -1 is passed, use until end of the file.
+ */
+ public Builder(@NonNull FileDescriptor fd, @IntRange(from = 0) long offset,
+ @IntRange(from = -1) long size) throws IOException {
+ try (FileInputStream fis = new FileInputStream(fd)) {
+ final FileChannel fc = fis.getChannel();
+ size = (size == -1) ? fc.size() - offset : size;
+ mBuffer = fc.map(FileChannel.MapMode.READ_ONLY, offset, size);
+ }
+ }
+
+ /**
+ * Constructs a builder from an asset manager and a file path in an asset directory.
+ *
+ * @param am the application's asset manager
+ * @param path the file name of the font data in the asset directory
+ */
+ public Builder(@NonNull AssetManager am, @NonNull String path) throws IOException {
+ final long nativeAsset = nGetNativeAsset(am, path, true /* is asset */, 0 /* cookie */);
+ if (nativeAsset == 0) {
+ throw new FileNotFoundException("Unable to open " + path);
+ }
+ final ByteBuffer b = nGetAssetBuffer(nativeAsset);
+ sAssetByteBufferRegistroy.registerNativeAllocation(b, nativeAsset);
+ if (b == null) {
+ throw new FileNotFoundException(path + " not found");
+ }
+ mBuffer = b;
+ }
+
+ /**
+ * Constructs a builder from resources.
+ *
+ * Resource ID must points the font file. XML font can not be used here.
+ *
+ * @param res the resource of this application.
+ * @param resId the resource ID of font file.
+ */
+ public Builder(@NonNull Resources res, int resId) throws IOException {
+ final TypedValue value = new TypedValue();
+ res.getValue(resId, value, true);
+ if (value.string == null) {
+ throw new FileNotFoundException(resId + " not found");
+ }
+ final String str = value.string.toString();
+ if (str.toLowerCase().endsWith(".xml")) {
+ throw new FileNotFoundException(resId + " must be font file.");
+ }
+ final long nativeAsset = nGetNativeAsset(res.getAssets(), str, false /* is asset */,
+ value.assetCookie);
+ if (nativeAsset == 0) {
+ throw new FileNotFoundException("Unable to open " + str);
+ }
+ final ByteBuffer b = nGetAssetBuffer(nativeAsset);
+ sAssetByteBufferRegistroy.registerNativeAllocation(b, nativeAsset);
+ if (b == null) {
+ throw new FileNotFoundException(str + " not found");
+ }
+ mBuffer = b;
+ }
+
+ /**
+ * Sets weight of the font.
+ *
+ * Tells the system the weight of the given font. If this function is not called, the system
+ * will resolve the weight value by reading font tables.
+ *
+ * Here are pairs of the common names and their values.
+ * <p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="center">Value</th>
+ * <th align="center">Name</th>
+ * <th align="center">Android Definition</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td align="center">100</td>
+ * <td align="center">Thin</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_THIN}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">200</td>
+ * <td align="center">Extra Light (Ultra Light)</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_EXTRA_LIGHT}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">300</td>
+ * <td align="center">Light</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_LIGHT}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">400</td>
+ * <td align="center">Normal (Regular)</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_NORMAL}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">500</td>
+ * <td align="center">Medium</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_MEDIUM}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">600</td>
+ * <td align="center">Semi Bold (Demi Bold)</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_SEMI_BOLD}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">700</td>
+ * <td align="center">Bold</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_BOLD}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">800</td>
+ * <td align="center">Extra Bold (Ultra Bold)</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_EXTRA_BOLD}</td>
+ * </tr>
+ * <tr>
+ * <td align="center">900</td>
+ * <td align="center">Black (Heavy)</td>
+ * <td align="center">{@link Font#FONT_WEIGHT_BLACK}</td>
+ * </tr>
+ * </tbody>
+ * </p>
+ *
+ * @see Font#FONT_WEIGHT_THIN
+ * @see Font#FONT_WEIGHT_EXTRA_LIGHT
+ * @see Font#FONT_WEIGHT_LIGHT
+ * @see Font#FONT_WEIGHT_NORMAL
+ * @see Font#FONT_WEIGHT_MEDIUM
+ * @see Font#FONT_WEIGHT_SEMI_BOLD
+ * @see Font#FONT_WEIGHT_BOLD
+ * @see Font#FONT_WEIGHT_EXTRA_BOLD
+ * @see Font#FONT_WEIGHT_BLACK
+ * @param weight a weight value
+ * @return this builder
+ */
+ public @NonNull Builder setWeight(@IntRange(from = 1, to = 1000) int weight) {
+ Preconditions.checkArgument(1 <= weight && weight <= 1000);
+ mWeight = weight;
+ return this;
+ }
+
+ /**
+ * Sets italic information of the font.
+ *
+ * Tells the system the style of the given font. If this function is not called, the system
+ * will resolve the style by reading font tables.
+ *
+ * For example, if you want to use italic font as upright font, call {@code
+ * setItalic(false)} explicitly.
+ *
+ * @param italic {@code true} if the font is italic. Otherwise {@code false}.
+ * @return this builder
+ */
+ public @NonNull Builder setItalic(boolean italic) {
+ mItalic = italic ? STYLE_ITALIC : STYLE_NORMAL;
+ return this;
+ }
+
+ /**
+ * Sets an index of the font collection. See {@link android.R.attr#ttcIndex}.
+ *
+ * @param ttcIndex An index of the font collection. If the font source is not font
+ * collection, do not call this method or specify 0.
+ * @return this builder
+ */
+ public @NonNull Builder setTtcIndex(@IntRange(from = 0) int ttcIndex) {
+ mTtcIndex = ttcIndex;
+ return this;
+ }
+
+ /**
+ * Sets the font variation settings.
+ *
+ * @param variationSettings see {@link FontVariationAxis#fromFontVariationSettings(String)}
+ * @return this builder
+ * @throws IllegalArgumentException If given string is not a valid font variation settings
+ * format.
+ */
+ public @NonNull Builder setFontVariationSettings(@Nullable String variationSettings) {
+ mAxes = FontVariationAxis.fromFontVariationSettings(variationSettings);
+ return this;
+ }
+
+ /**
+ * Sets the font variation settings.
+ *
+ * @param axes an array of font variation axis tag-value pairs
+ * @return this builder
+ */
+ public @NonNull Builder setFontVariationSettings(@Nullable FontVariationAxis[] axes) {
+ mAxes = axes;
+ return this;
+ }
+
+ /**
+ * Creates the font based on the configured values.
+ * @return the Font object
+ */
+ public @Nullable Font build() {
+ if (mWeight == NOT_SPECIFIED || mItalic == NOT_SPECIFIED) {
+ final int packed = FontFileUtil.analyzeStyle(mBuffer, mTtcIndex, mAxes);
+ if (FontFileUtil.isSuccess(packed)) {
+ if (mWeight == NOT_SPECIFIED) {
+ mWeight = FontFileUtil.unpackWeight(packed);
+ }
+ if (mItalic == NOT_SPECIFIED) {
+ mItalic = FontFileUtil.unpackItalic(packed) ? STYLE_ITALIC : STYLE_NORMAL;
+ }
+ } else {
+ mWeight = 400;
+ mItalic = STYLE_NORMAL;
+ }
+ }
+ final boolean italic = (mItalic == STYLE_ITALIC);
+ final long builderPtr = nInitBuilder();
+ if (mAxes != null) {
+ for (FontVariationAxis axis : mAxes) {
+ nAddAxis(builderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue());
+ }
+ }
+ final long ptr = nBuild(builderPtr, mBuffer, mWeight, italic, mTtcIndex);
+ final Font font = new Font(ptr, mWeight, italic, mTtcIndex, mAxes);
+ sFontRegistory.registerNativeAllocation(font, ptr);
+ return font;
+ }
+
+ /**
+ * Native methods for accessing underlying buffer in Asset
+ */
+ private static native long nGetNativeAsset(
+ @NonNull AssetManager am, @NonNull String path, boolean isAsset, int cookie);
+ private static native ByteBuffer nGetAssetBuffer(long nativeAsset);
+ @CriticalNative
+ private static native long nGetReleaseNativeAssetFunc();
+
+ /**
+ * Native methods for creating Font
+ */
+ private static native long nInitBuilder();
+ @CriticalNative
+ private static native void nAddAxis(long builderPtr, int tag, float value);
+ private static native long nBuild(
+ long builderPtr, ByteBuffer buffer, int weight, boolean italic, int ttcIndex);
+ @CriticalNative
+ private static native long nGetReleaseNativeFont();
+ }
+
+ private final long mNativePtr; // address of the shared ptr of minikin::Font
+ private final @IntRange(from = 0, to = 1000) int mWeight;
+ private final boolean mItalic;
+ private final @IntRange(from = 0) int mTtcIndex;
+ private final @Nullable FontVariationAxis[] mAxes;
+
+ /**
+ * Use Builder instead
+ */
+ private Font(long nativePtr, @IntRange(from = 0, to = 1000) int weight, boolean italic,
+ @IntRange(from = 0) int ttcIndex, @Nullable FontVariationAxis[] axes) {
+ mWeight = weight;
+ mItalic = italic;
+ mNativePtr = nativePtr;
+ mTtcIndex = ttcIndex;
+ mAxes = axes;
+ }
+
+ /**
+ * Get a weight value associated with this font.
+ *
+ * @see Builder#setWeight(int)
+ * @return a weight value
+ */
+ public @IntRange(from = 0, to = 1000)int getWeight() {
+ return mWeight;
+ }
+
+ /**
+ * Returns true if this font is marked as italic, otherwise returns false.
+ *
+ * @see Builder#setItalic(boolean)
+ * @return true if italic, otherwise false
+ */
+ public boolean isItalic() {
+ return mItalic;
+ }
+
+ /**
+ * Get a TTC index value associated with this font.
+ *
+ * If TTF/OTF file is provided, this value is always 0.
+ *
+ * @see Builder#setTtcIndex(int)
+ * @return a TTC index value
+ */
+ public @IntRange(from = 0) int getTtcIndex() {
+ return mTtcIndex;
+ }
+
+ /**
+ * Get a font variation settings associated with this font
+ *
+ * @see Builder#setFontVariationSettings(String)
+ * @see Builder#setFontVariationSettings(FontVariationAxis[])
+ * @return font variation settings
+ */
+ public @Nullable FontVariationAxis[] getAxes() {
+ return mAxes;
+ }
+
+ /** @hide */
+ public long getNativePtr() {
+ return mNativePtr;
+ }
+}
diff --git a/graphics/java/android/graphics/fonts/FontFileUtil.java b/graphics/java/android/graphics/fonts/FontFileUtil.java
index d15f581..f8b456b 100644
--- a/graphics/java/android/graphics/fonts/FontFileUtil.java
+++ b/graphics/java/android/graphics/fonts/FontFileUtil.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
-import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -46,6 +45,13 @@
return (packed & 0x10000) != 0;
}
+ /**
+ * Returns true if the analyzeStyle succeeded
+ */
+ public static boolean isSuccess(int packed) {
+ return packed != ANALYZE_ERROR;
+ }
+
private static int pack(@IntRange(from = 0, to = 1000) int weight, boolean italic) {
return weight | (italic ? 0x10000 : 0);
}
@@ -55,12 +61,13 @@
private static final int TTC_TAG = 0x74746366;
private static final int OS2_TABLE_TAG = 0x4F532F32;
+ private static final int ANALYZE_ERROR = 0xFFFFFFFF;
+
/**
* Analyze the font file returns packed style info
*/
public static final int analyzeStyle(@NonNull ByteBuffer buffer,
- @IntRange(from = 0) int ttcIndex, @Nullable FontVariationAxis[] varSettings)
- throws IOException {
+ @IntRange(from = 0) int ttcIndex, @Nullable FontVariationAxis[] varSettings) {
int weight = -1;
int italic = -1;
if (varSettings != null) {
@@ -88,7 +95,7 @@
if (magicNumber == TTC_TAG) {
// TTC file.
if (ttcIndex >= buffer.getInt(8 /* offset to number of fonts in TTC */)) {
- throw new IOException("Font index out of bounds");
+ return ANALYZE_ERROR;
}
fontFileOffset = buffer.getInt(
12 /* offset to array of offsets of font files */ + 4 * ttcIndex);
@@ -96,7 +103,7 @@
int sfntVersion = buffer.getInt(fontFileOffset);
if (sfntVersion != SFNT_VERSION_1 && sfntVersion != SFNT_VERSION_OTTO) {
- throw new IOException("Unknown font file format");
+ return ANALYZE_ERROR;
}
int numTables = buffer.getShort(fontFileOffset + 4 /* offset to number of tables */);
diff --git a/graphics/java/android/graphics/fonts/FontVariationAxis.java b/graphics/java/android/graphics/fonts/FontVariationAxis.java
index 1b7408a..2a902c5 100644
--- a/graphics/java/android/graphics/fonts/FontVariationAxis.java
+++ b/graphics/java/android/graphics/fonts/FontVariationAxis.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.text.TextUtils;
import java.util.ArrayList;
@@ -27,8 +28,10 @@
* Class that holds information about single font variation axis.
*/
public final class FontVariationAxis {
+ @UnsupportedAppUsage
private final int mTag;
private final String mTagString;
+ @UnsupportedAppUsage
private final float mStyleValue;
/**
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 4a91705..1836f00 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Matrix;
@@ -118,6 +119,7 @@
private ParcelFileDescriptor mInput;
+ @UnsupportedAppUsage
private Page mCurrentPage;
/** @hide */
@@ -242,6 +244,7 @@
}
}
+ @UnsupportedAppUsage
private void doClose() {
if (mCurrentPage != null) {
mCurrentPage.close();
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 8502309..4f4ca3f 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -128,7 +128,11 @@
public static final int FLAG_STRONGBOX = 1 << 4;
// States
- public enum State { UNLOCKED, LOCKED, UNINITIALIZED };
+ public enum State {
+ UNLOCKED,
+ LOCKED,
+ UNINITIALIZED
+ };
private int mError = NO_ERROR;
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 402fbad..9f82d0f 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -474,14 +474,13 @@
// Update the given paint with alpha and color filter. Return nullptr if no color filter is
// specified and root alpha is 1. Otherwise, return updated paint.
SkPaint* Tree::updatePaint(SkPaint* outPaint, TreeProperties* prop) {
- if (prop->getRootAlpha() == 1.0f && prop->getColorFilter() == nullptr) {
- return nullptr;
- } else {
+ // HWUI always draws VD with bilinear filtering.
+ outPaint->setFilterQuality(kLow_SkFilterQuality);
+ if (prop->getRootAlpha() < 1.0f || prop->getColorFilter() != nullptr) {
outPaint->setColorFilter(sk_ref_sp(prop->getColorFilter()));
- outPaint->setFilterQuality(kLow_SkFilterQuality);
outPaint->setAlpha(prop->getRootAlpha() * 255);
- return outPaint;
}
+ return outPaint;
}
Bitmap& Tree::getBitmapUpdateIfDirty() {
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 46e39aa..b9748af 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -257,9 +257,8 @@
SkRect dst = SkRect::MakeLTRB(dstLeft, dstTop, dstRight, dstBottom);
PaintCoW filteredPaint(paint);
- // Besides kNone, the other three SkFilterQualities are treated the same. And Android's
- // Java API only supports kLow and kNone anyway.
- if (!filteredPaint || filteredPaint->getFilterQuality() == kNone_SkFilterQuality) {
+ // HWUI always draws 9-patches with bilinear filtering, regardless of what is set in the Paint.
+ if (!filteredPaint || filteredPaint->getFilterQuality() != kLow_SkFilterQuality) {
filteredPaint.writeable().setFilterQuality(kLow_SkFilterQuality);
}
sk_sp<SkColorFilter> colorFilter;
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 3a0a58e..60cad90 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -1523,7 +1523,7 @@
// this should never happen as mWrappedKey is initialized in
// JNI after construction of the KeyRequest object. The check
// is needed here to guarantee @NonNull annotation.
- throw new RuntimeException("Cerfificate is not initialized");
+ throw new RuntimeException("Certificate is not initialized");
}
return mWrappedKey;
}
@@ -1537,7 +1537,7 @@
// this should never happen as mCertificateData is initialized in
// JNI after construction of the KeyRequest object. The check
// is needed here to guarantee @NonNull annotation.
- throw new RuntimeException("Cerfificate is not initialized");
+ throw new RuntimeException("Certificate is not initialized");
}
return mCertificateData;
}
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 61c412d..bcff5bf 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -1794,18 +1794,17 @@
public @interface MediaError {}
/* Do not change these values without updating their counterparts
- * in include/media/mediaplayer2.h!
+ * in include/media/MediaPlayer2Types.h!
*/
/** Unspecified media player info.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
public static final int MEDIA_INFO_UNKNOWN = 1;
- /** The player switched to this datas source because it is the
- * next-to-be-played in the playlist.
+ /** The player just started the playback of this datas source.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
- public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
+ public static final int MEDIA_INFO_DATA_SOURCE_START = 2;
/** The player just pushed the very first video frame for rendering.
* @see android.media.MediaPlayer2.EventCallback#onInfo
@@ -1820,12 +1819,13 @@
/** The player just completed the playback of this data source.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
- public static final int MEDIA_INFO_PLAYBACK_COMPLETE = 5;
+ public static final int MEDIA_INFO_DATA_SOURCE_END = 5;
- /** The player just completed the playback of the full playlist.
+ /** The player just completed the playback of all data sources set by {@link #setDataSource},
+ * {@link #setNextDataSource} and {@link #setNextDataSources}.
* @see android.media.MediaPlayer2.EventCallback#onInfo
*/
- public static final int MEDIA_INFO_PLAYLIST_END = 6;
+ public static final int MEDIA_INFO_DATA_SOURCE_LIST_END = 6;
/** The player just prepared a data source.
* @see android.media.MediaPlayer2.EventCallback#onInfo
@@ -1927,11 +1927,11 @@
*/
@IntDef(flag = false, prefix = "MEDIA_INFO", value = {
MEDIA_INFO_UNKNOWN,
- MEDIA_INFO_STARTED_AS_NEXT,
+ MEDIA_INFO_DATA_SOURCE_START,
MEDIA_INFO_VIDEO_RENDERING_START,
MEDIA_INFO_AUDIO_RENDERING_START,
- MEDIA_INFO_PLAYBACK_COMPLETE,
- MEDIA_INFO_PLAYLIST_END,
+ MEDIA_INFO_DATA_SOURCE_END,
+ MEDIA_INFO_DATA_SOURCE_LIST_END,
MEDIA_INFO_PREPARED,
MEDIA_INFO_VIDEO_TRACK_LAGGING,
MEDIA_INFO_BUFFERING_START,
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index dccfd7a..95ba00f 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -210,6 +210,22 @@
@Override
void process() {
stayAwake(true);
+
+ // TODO: remove this block when native code sends MEDIA_INFO_DATA_SOURCE_START
+ // when pipeline is created.
+ if (getState() == PLAYER_STATE_PREPARED) {
+ final DataSourceDesc dsd;
+ synchronized (mSrcLock) {
+ dsd = mCurrentDSD;
+ }
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ MediaPlayer2Impl.this, dsd, MEDIA_INFO_DATA_SOURCE_START, 0));
+ }
+ }
+ }
+
_start();
}
});
@@ -246,6 +262,22 @@
@Override
void process() {
stayAwake(false);
+
+ // TODO: remove this block when native code allows prepared -> pause
+ // and sends MEDIA_INFO_DATA_SOURCE_START when pipeline is created.
+ if (getState() == PLAYER_STATE_PREPARED) {
+ final DataSourceDesc dsd;
+ synchronized (mSrcLock) {
+ dsd = mCurrentDSD;
+ }
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ MediaPlayer2Impl.this, dsd, MEDIA_INFO_DATA_SOURCE_START, 0));
+ }
+ }
+ }
+
_pause();
}
});
@@ -370,8 +402,6 @@
* after current data source is finished.
*
* @param dsd the descriptor of data source you want to play after current one
- * @throws IllegalStateException if it is called in an invalid state
- * @throws NullPointerException if dsd is null
*/
@Override
public void setNextDataSource(@NonNull DataSourceDesc dsd) {
@@ -384,14 +414,8 @@
mNextDSDs.add(dsd);
mNextSrcId = mSrcIdGenerator++;
mNextSourceState = NEXT_SOURCE_STATE_INIT;
- mNextSourcePlayPending = false;
}
- int state = getState();
- if (state != PLAYER_STATE_IDLE) {
- synchronized (mSrcLock) {
- prepareNextDataSource_l();
- }
- }
+ prepareNextDataSource();
}
});
}
@@ -400,8 +424,6 @@
* Sets a list of data sources to be played sequentially after current data source is done.
*
* @param dsds the list of data sources you want to play after current one
- * @throws IllegalStateException if it is called in an invalid state
- * @throws IllegalArgumentException if dsds is null or empty, or contains null DataSourceDesc
*/
@Override
public void setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
@@ -422,14 +444,8 @@
mNextDSDs = new ArrayList(dsds);
mNextSrcId = mSrcIdGenerator++;
mNextSourceState = NEXT_SOURCE_STATE_INIT;
- mNextSourcePlayPending = false;
}
- int state = getState();
- if (state != PLAYER_STATE_IDLE) {
- synchronized (mSrcLock) {
- prepareNextDataSource_l();
- }
- }
+ prepareNextDataSource();
}
});
}
@@ -904,67 +920,100 @@
private native void nativeHandleDataSourceCallback(
boolean isCurrent, long srcId, Media2DataSource dataSource);
- // This function shall be called with |mSrcLock| acquired.
- private void prepareNextDataSource_l() {
- if (mNextDSDs == null || mNextDSDs.isEmpty()
- || mNextSourceState != NEXT_SOURCE_STATE_INIT) {
- // There is no next source or it's in preparing or prepared state.
- return;
+ /**
+ * @return true if there is a next data source, false otherwise.
+ */
+ // This function should be always called on |mHandlerThread|.
+ private boolean prepareNextDataSource() {
+ if (Looper.myLooper() != mHandlerThread.getLooper()) {
+ Log.e(TAG, "prepareNextDataSource: called on wrong looper");
}
- try {
- mNextSourceState = NEXT_SOURCE_STATE_PREPARING;
- handleDataSource(false /* isCurrent */, mNextDSDs.get(0), mNextSrcId);
- } catch (Exception e) {
- Message msg2 = mTaskHandler.obtainMessage(
- MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
- final long nextSrcId = mNextSrcId;
- mTaskHandler.post(new Runnable() {
- @Override
- public void run() {
- mTaskHandler.handleMessage(msg2, nextSrcId);
- }
- });
+ boolean hasNextDSD;
+ synchronized (mSrcLock) {
+ hasNextDSD = (mNextDSDs != null && !mNextDSDs.isEmpty());
}
+
+ int state = getState();
+ if (state == PLAYER_STATE_ERROR || state == PLAYER_STATE_IDLE) {
+ // Current source has not been prepared yet.
+ return hasNextDSD;
+ }
+
+ synchronized (mSrcLock) {
+ if (!hasNextDSD || mNextSourceState != NEXT_SOURCE_STATE_INIT) {
+ // There is no next source or it's in preparing or prepared state.
+ return hasNextDSD;
+ }
+
+ try {
+ mNextSourceState = NEXT_SOURCE_STATE_PREPARING;
+ handleDataSource(false /* isCurrent */, mNextDSDs.get(0), mNextSrcId);
+ } catch (Exception e) {
+ Message msg = mTaskHandler.obtainMessage(
+ MEDIA_ERROR, MEDIA_ERROR_IO, MEDIA_ERROR_UNKNOWN, null);
+ mTaskHandler.handleMessage(msg, mNextSrcId);
+
+ mNextDSDs.remove(0);
+ // make a new SrcId to obsolete notification for previous one.
+ mNextSrcId = mSrcIdGenerator++;
+ mNextSourceState = NEXT_SOURCE_STATE_INIT;
+ return prepareNextDataSource();
+ }
+ }
+ return hasNextDSD;
}
- // This function shall be called with |mSrcLock| acquired.
- private void playNextDataSource_l() {
- if (mNextDSDs == null || mNextDSDs.isEmpty()) {
- return;
+ // This function should be always called on |mHandlerThread|.
+ private void playNextDataSource() {
+ if (Looper.myLooper() != mHandlerThread.getLooper()) {
+ Log.e(TAG, "playNextDataSource: called on wrong looper");
}
- if (mNextSourceState == NEXT_SOURCE_STATE_PREPARED) {
- // Switch to next source only when it's in prepared state.
- mCurrentDSD = mNextDSDs.get(0);
- mCurrentSrcId = mNextSrcId;
- mBufferedPercentageCurrent.set(mBufferedPercentageNext.get());
- mNextDSDs.remove(0);
- mNextSrcId = mSrcIdGenerator++; // make it different from mCurrentSrcId
- mBufferedPercentageNext.set(0);
- mNextSourceState = NEXT_SOURCE_STATE_INIT;
- mNextSourcePlayPending = false;
+ boolean hasNextDSD = false;
+ synchronized (mSrcLock) {
+ if (mNextDSDs != null && !mNextDSDs.isEmpty()) {
+ hasNextDSD = true;
+ if (mNextSourceState == NEXT_SOURCE_STATE_PREPARED) {
+ // Switch to next source only when it has been prepared.
+ mCurrentDSD = mNextDSDs.get(0);
+ mCurrentSrcId = mNextSrcId;
+ mBufferedPercentageCurrent.set(mBufferedPercentageNext.get());
+ mNextDSDs.remove(0);
+ mNextSrcId = mSrcIdGenerator++; // make it different from |mCurrentSrcId|
+ mBufferedPercentageNext.set(0);
+ mNextSourceState = NEXT_SOURCE_STATE_INIT;
- long srcId = mCurrentSrcId;
- try {
- nativePlayNextDataSource(srcId);
- } catch (Exception e) {
- Message msg2 = mTaskHandler.obtainMessage(
- MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
- mTaskHandler.post(new Runnable() {
- @Override
- public void run() {
+ long srcId = mCurrentSrcId;
+ try {
+ nativePlayNextDataSource(srcId);
+ } catch (Exception e) {
+ Message msg2 = mTaskHandler.obtainMessage(
+ MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
mTaskHandler.handleMessage(msg2, srcId);
+ // Keep |mNextSourcePlayPending|
+ hasNextDSD = prepareNextDataSource();
}
- });
- }
+ if (hasNextDSD) {
+ stayAwake(true);
- // Wait for MEDIA2_INFO_STARTED_AS_NEXT to prepare next source.
- } else {
- if (mNextSourceState == NEXT_SOURCE_STATE_INIT) {
- prepareNextDataSource_l();
+ // Now a new current src is playing.
+ // Wait for MEDIA_INFO_DATA_SOURCE_START to prepare next source.
+ mNextSourcePlayPending = false;
+ }
+ } else if (mNextSourceState == NEXT_SOURCE_STATE_INIT) {
+ hasNextDSD = prepareNextDataSource();
+ }
}
- mNextSourcePlayPending = true;
+ }
+
+ if (!hasNextDSD) {
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ MediaPlayer2Impl.this, null, MEDIA_INFO_DATA_SOURCE_LIST_END, 0));
+ }
+ }
}
}
@@ -2664,6 +2713,21 @@
final int what = msg.arg1;
final int extra = msg.arg2;
+ final DataSourceDesc dsd;
+ boolean isCurrentSrcId = false;
+ boolean isNextSrcId = false;
+ synchronized (mSrcLock) {
+ if (srcId == mCurrentSrcId) {
+ dsd = mCurrentDSD;
+ isCurrentSrcId = true;
+ } else if (mNextDSDs != null && !mNextDSDs.isEmpty() && srcId == mNextSrcId) {
+ dsd = mNextDSDs.get(0);
+ isNextSrcId = true;
+ } else {
+ return;
+ }
+ }
+
switch(msg.what) {
case MEDIA_PREPARED:
{
@@ -2678,25 +2742,6 @@
sendMessage(msg2);
}
- final DataSourceDesc dsd;
- synchronized (mSrcLock) {
- Log.i(TAG, "MEDIA_PREPARED: srcId=" + srcId
- + ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId);
- if (srcId == mCurrentSrcId) {
- dsd = mCurrentDSD;
- prepareNextDataSource_l();
- } else if (mNextDSDs != null && !mNextDSDs.isEmpty()
- && srcId == mNextSrcId) {
- dsd = mNextDSDs.get(0);
- mNextSourceState = NEXT_SOURCE_STATE_PREPARED;
- if (mNextSourcePlayPending) {
- playNextDataSource_l();
- }
- } else {
- dsd = null;
- }
- }
-
if (dsd != null) {
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
@@ -2705,6 +2750,21 @@
}
}
}
+
+ synchronized (mSrcLock) {
+ Log.i(TAG, "MEDIA_PREPARED: srcId=" + srcId
+ + ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId);
+
+ if (isCurrentSrcId) {
+ prepareNextDataSource();
+ } else if (isNextSrcId) {
+ mNextSourceState = NEXT_SOURCE_STATE_PREPARED;
+ if (mNextSourcePlayPending) {
+ playNextDataSource();
+ }
+ }
+ }
+
synchronized (mTaskLock) {
if (mCurrentTask != null
&& mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE
@@ -2739,7 +2799,7 @@
synchronized (mEventCbLock) {
for (Pair<Executor, DrmEventCallback> cb : mDrmEventCallbackRecords) {
cb.first.execute(() -> cb.second.onDrmInfo(
- mMediaPlayer, mCurrentDSD, drmInfo));
+ mMediaPlayer, dsd, drmInfo));
}
}
}
@@ -2751,22 +2811,25 @@
case MEDIA_PLAYBACK_COMPLETE:
{
- final DataSourceDesc dsd = mCurrentDSD;
- synchronized (mSrcLock) {
- if (srcId == mCurrentSrcId) {
+ if (isCurrentSrcId) {
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
+ }
+ }
+ stayAwake(false);
+
+ synchronized (mSrcLock) {
+ mNextSourcePlayPending = true;
+
Log.i(TAG, "MEDIA_PLAYBACK_COMPLETE: srcId=" + srcId
+ ", currentSrcId=" + mCurrentSrcId + ", nextSrcId=" + mNextSrcId);
- playNextDataSource_l();
}
+
+ playNextDataSource();
}
- synchronized (mEventCbLock) {
- for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
- cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, dsd, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
- }
- }
- stayAwake(false);
return;
}
@@ -2793,21 +2856,18 @@
{
final int percent = msg.arg1;
synchronized (mEventCbLock) {
- if (srcId == mCurrentSrcId) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ mMediaPlayer, dsd, MEDIA_INFO_BUFFERING_UPDATE,
+ percent));
+ }
+ }
+
+ synchronized (mSrcLock) {
+ if (isCurrentSrcId) {
mBufferedPercentageCurrent.set(percent);
- for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
- cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, mCurrentDSD, MEDIA_INFO_BUFFERING_UPDATE,
- percent));
- }
- } else if (srcId == mNextSrcId && !mNextDSDs.isEmpty()) {
+ } else if (isNextSrcId) {
mBufferedPercentageNext.set(percent);
- DataSourceDesc nextDSD = mNextDSDs.get(0);
- for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
- cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, nextDSD, MEDIA_INFO_BUFFERING_UPDATE,
- percent));
- }
}
}
return;
@@ -2843,7 +2903,7 @@
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onVideoSizeChanged(
- mMediaPlayer, mCurrentDSD, width, height));
+ mMediaPlayer, dsd, width, height));
}
}
return;
@@ -2855,9 +2915,9 @@
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onError(
- mMediaPlayer, mCurrentDSD, what, extra));
+ mMediaPlayer, dsd, what, extra));
cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, mCurrentDSD, MEDIA_INFO_PLAYBACK_COMPLETE, 0));
+ mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0));
}
}
stayAwake(false);
@@ -2866,10 +2926,17 @@
case MEDIA_INFO:
{
+ synchronized (mEventCbLock) {
+ for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
+ cb.first.execute(() -> cb.second.onInfo(
+ mMediaPlayer, dsd, what, extra));
+ }
+ }
+
switch (msg.arg1) {
- case MEDIA_INFO_STARTED_AS_NEXT:
- if (srcId == mCurrentSrcId) {
- prepareNextDataSource_l();
+ case MEDIA_INFO_DATA_SOURCE_START:
+ if (isCurrentSrcId) {
+ prepareNextDataSource();
}
break;
@@ -2904,13 +2971,6 @@
}
break;
}
-
- synchronized (mEventCbLock) {
- for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
- cb.first.execute(() -> cb.second.onInfo(
- mMediaPlayer, mCurrentDSD, what, extra));
- }
- }
// No real default action so far.
return;
}
@@ -2938,7 +2998,7 @@
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onTimedText(
- mMediaPlayer, mCurrentDSD, text));
+ mMediaPlayer, dsd, text));
}
}
return;
@@ -2953,7 +3013,7 @@
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onSubtitleData(
- mMediaPlayer, mCurrentDSD, data));
+ mMediaPlayer, dsd, data));
}
}
}
@@ -2974,7 +3034,7 @@
synchronized (mEventCbLock) {
for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
cb.first.execute(() -> cb.second.onTimedMetaDataAvailable(
- mMediaPlayer, mCurrentDSD, data));
+ mMediaPlayer, dsd, data));
}
}
return;
@@ -3022,19 +3082,6 @@
}
switch (what) {
- case MEDIA_INFO:
- if (arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- // this acquires the wakelock if needed, and sets the client side state
- mp.play();
- }
- }).start();
- Thread.yield();
- }
- break;
-
case MEDIA_DRM_INFO:
// We need to derive mDrmInfoImpl before prepare() returns so processing it here
// before the notification is sent to TaskHandler below. TaskHandler runs in the
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 54541f0..7cf8828 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -43,27 +43,27 @@
#define FIND_CLASS(var, className) \
var = env->FindClass(className); \
- LOG_FATAL_IF(! (var), "Unable to find class " className);
+ LOG_FATAL_IF(! (var), "Unable to find class %s", className);
#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
- LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
+ LOG_FATAL_IF(! (var), "Unable to find field %s", fieldName);
#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
- LOG_FATAL_IF(! (var), "Unable to find method " fieldName);
+ LOG_FATAL_IF(! (var), "Unable to find method %s", fieldName);
#define GET_STATIC_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetStaticFieldID(clazz, fieldName, fieldDescriptor); \
- LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
+ LOG_FATAL_IF(! (var), "Unable to find field %s", fieldName);
#define GET_STATIC_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
var = env->GetStaticMethodID(clazz, fieldName, fieldDescriptor); \
- LOG_FATAL_IF(! (var), "Unable to find static method " fieldName);
+ LOG_FATAL_IF(! (var), "Unable to find static method %s", fieldName);
-#define GET_STATIC_OBJECT_FIELD(var, clazz, fieldName) \
- var = env->GetStaticObjectField(clazz, fieldName); \
- LOG_FATAL_IF(! (var), "Unable to find static object field " fieldName);
+#define GET_STATIC_OBJECT_FIELD(var, clazz, fieldId) \
+ var = env->GetStaticObjectField(clazz, fieldId); \
+ LOG_FATAL_IF(! (var), "Unable to find static object field %p", fieldId);
struct RequestFields {
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
index ff70e97..a7217ec 100644
--- a/packages/ExtServices/AndroidManifest.xml
+++ b/packages/ExtServices/AndroidManifest.xml
@@ -55,12 +55,6 @@
<intent-filter>
<action android:name="android.service.autofill.AutofillFieldClassificationService" />
</intent-filter>
- <meta-data
- android:name="android.autofill.field_classification.default_algorithm"
- android:resource="@string/autofill_field_classification_default_algorithm" />
- <meta-data
- android:name="android.autofill.field_classification.available_algorithms"
- android:resource="@array/autofill_field_classification_available_algorithms" />
</service>
<library android:name="android.ext.services"/>
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index a539b1f..9d19898 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -17,15 +17,16 @@
package android.ext.services.notification;
import static android.app.NotificationManager.IMPORTANCE_MIN;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking
+ .USER_SENTIMENT_NEGATIVE;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
-import android.ext.services.R;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@@ -193,23 +194,27 @@
if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey());
ArrayList<Notification.Action> actions =
mSmartActionsHelper.suggestActions(this, sbn);
- if (actions.isEmpty()) {
- return null;
- }
- return createEnqueuedNotificationAdjustment(sbn, actions);
+ ArrayList<CharSequence> replies = mSmartActionsHelper.suggestReplies(this, sbn);
+ return createEnqueuedNotificationAdjustment(sbn, actions, replies);
}
/** A convenience helper for creating an adjustment for an SBN. */
+ @Nullable
private Adjustment createEnqueuedNotificationAdjustment(
@NonNull StatusBarNotification statusBarNotification,
- @NonNull ArrayList<Notification.Action> smartActions) {
+ @NonNull ArrayList<Notification.Action> smartActions,
+ @NonNull ArrayList<CharSequence> smartReplies) {
+ if (smartActions.isEmpty() && smartReplies.isEmpty()) {
+ return null;
+ }
Bundle signals = new Bundle();
signals.putParcelableArrayList(Adjustment.KEY_SMART_ACTIONS, smartActions);
+ signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies);
return new Adjustment(
statusBarNotification.getPackageName(),
statusBarNotification.getKey(),
signals,
- "smart action" /* explanation */,
+ "smart action, reply" /* explanation */,
statusBarNotification.getUserId());
}
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index ed5cbab..9d33bd9 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -24,6 +24,7 @@
import android.os.Bundle;
import android.os.Parcelable;
import android.os.Process;
+import android.os.SystemProperties;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -32,13 +33,13 @@
import android.view.textclassifier.TextClassifier;
import android.view.textclassifier.TextLinks;
-import com.android.internal.util.Preconditions;
-
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
public class SmartActionsHelper {
- private static final ArrayList<Notification.Action> EMPTY_LIST = new ArrayList<>();
+ private static final ArrayList<Notification.Action> EMPTY_ACTION_LIST = new ArrayList<>();
+ private static final ArrayList<CharSequence> EMPTY_REPLY_LIST = new ArrayList<>();
// If a notification has any of these flags set, it's inelgibile for actions being added.
private static final int FLAG_MASK_INELGIBILE_FOR_ACTIONS =
@@ -49,6 +50,10 @@
private static final int MAX_ACTION_EXTRACTION_TEXT_LENGTH = 400;
private static final int MAX_ACTIONS_PER_LINK = 1;
private static final int MAX_SMART_ACTIONS = Notification.MAX_ACTION_BUTTONS;
+ // Allow us to test out smart reply with dumb suggestions, it is disabled by default.
+ // TODO: Removed this once we have the model.
+ private static final String SYS_PROP_SMART_REPLIES_EXPERIMENT =
+ "persist.sys.smart_replies_experiment";
SmartActionsHelper() {}
@@ -62,14 +67,14 @@
ArrayList<Notification.Action> suggestActions(
@Nullable Context context, @NonNull StatusBarNotification sbn) {
if (!isEligibleForActionAdjustment(sbn)) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
if (context == null) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
TextClassificationManager tcm = context.getSystemService(TextClassificationManager.class);
if (tcm == null) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
Notification.Action[] actions = sbn.getNotification().actions;
int numOfExistingActions = actions == null ? 0: actions.length;
@@ -79,6 +84,18 @@
getMostSalientActionText(sbn.getNotification()), maxSmartActions);
}
+ ArrayList<CharSequence> suggestReplies(
+ @Nullable Context context, @NonNull StatusBarNotification sbn) {
+ if (!isEligibleForReplyAdjustment(sbn)) {
+ return EMPTY_REPLY_LIST;
+ }
+ if (context == null) {
+ return EMPTY_REPLY_LIST;
+ }
+ // TODO: replaced this with our model when it is ready.
+ return new ArrayList<>(Arrays.asList("Yes, please", "No, thanks"));
+ }
+
/**
* Returns whether a notification is eligible for action adjustments.
*
@@ -108,6 +125,17 @@
|| hasInlineReply(notification);
}
+ private boolean isEligibleForReplyAdjustment(@NonNull StatusBarNotification sbn) {
+ if (!SystemProperties.getBoolean(SYS_PROP_SMART_REPLIES_EXPERIMENT, false)) {
+ return false;
+ }
+ Notification notification = sbn.getNotification();
+ if (notification.actions == null) {
+ return false;
+ }
+ return hasInlineReply(sbn.getNotification());
+ }
+
private boolean hasInlineReply(Notification notification) {
Notification.Action[] actions = notification.actions;
if (actions == null) {
@@ -151,7 +179,7 @@
@NonNull TextClassificationManager tcm, @Nullable CharSequence text,
int maxSmartActions) {
if (TextUtils.isEmpty(text)) {
- return EMPTY_LIST;
+ return EMPTY_ACTION_LIST;
}
TextClassifier textClassifier = tcm.getTextClassifier();
diff --git a/packages/PackageInstaller/.gitignore b/packages/PackageInstaller/.gitignore
new file mode 100644
index 0000000..7866e9e
--- /dev/null
+++ b/packages/PackageInstaller/.gitignore
@@ -0,0 +1,6 @@
+bin/
+gen/
+*.iml
+.project
+.classpath
+project.properties
diff --git a/packages/PackageInstaller/Android.mk b/packages/PackageInstaller/Android.mk
new file mode 100644
index 0000000..f556b48
--- /dev/null
+++ b/packages/PackageInstaller/Android.mk
@@ -0,0 +1,24 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_USE_AAPT2 := true
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ $(call all-java-files-under, src)
+
+LOCAL_STATIC_ANDROID_LIBRARIES += \
+ androidx.leanback_leanback
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ xz-java \
+ androidx.annotation_annotation
+
+LOCAL_PACKAGE_NAME := PackageInstaller
+
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+include $(BUILD_PACKAGE)
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
new file mode 100644
index 0000000..f4b9cef
--- /dev/null
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.packageinstaller">
+
+ <uses-permission android:name="android.permission.MANAGE_USERS" />
+ <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
+ <uses-permission android:name="android.permission.DELETE_PACKAGES" />
+ <uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" />
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+ <uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" />
+ <uses-permission android:name="android.permission.USE_RESERVED_DISK" />
+ <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
+ <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+
+ <uses-permission android:name="com.google.android.permission.INSTALL_WEARABLE_PACKAGES" />
+
+ <application android:name=".PackageInstallerApplication"
+ android:label="@string/app_name"
+ android:allowBackup="false"
+ android:theme="@style/DialogWhenLarge"
+ android:supportsRtl="true"
+ android:defaultToDeviceProtectedStorage="true"
+ android:directBootAware="true">
+
+ <receiver android:name=".TemporaryFileManager"
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
+ </receiver>
+
+ <activity android:name=".InstallStart"
+ android:exported="true"
+ android:excludeFromRecents="true">
+ <intent-filter android:priority="1">
+ <action android:name="android.intent.action.VIEW" />
+ <action android:name="android.intent.action.INSTALL_PACKAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="file" />
+ <data android:scheme="content" />
+ <data android:mimeType="application/vnd.android.package-archive" />
+ </intent-filter>
+ <intent-filter android:priority="1">
+ <action android:name="android.intent.action.INSTALL_PACKAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="file" />
+ <data android:scheme="package" />
+ <data android:scheme="content" />
+ </intent-filter>
+ <intent-filter android:priority="1">
+ <action android:name="android.content.pm.action.CONFIRM_INSTALL" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".InstallStaging"
+ android:exported="false" />
+
+ <activity android:name=".DeleteStagedFileOnResult"
+ android:exported="false" />
+
+ <activity android:name=".PackageInstallerActivity"
+ android:exported="false" />
+
+ <activity android:name=".InstallInstalling"
+ android:theme="@style/DialogWhenLargeNoAnimation"
+ android:exported="false" />
+
+ <receiver android:name=".InstallEventReceiver"
+ android:permission="android.permission.INSTALL_PACKAGES"
+ android:exported="true">
+ <intent-filter android:priority="1">
+ <action android:name="com.android.packageinstaller.ACTION_INSTALL_COMMIT" />
+ </intent-filter>
+ </receiver>
+
+ <activity android:name=".InstallSuccess"
+ android:theme="@style/DialogWhenLargeNoAnimation"
+ android:exported="false" />
+
+ <activity android:name=".InstallFailed"
+ android:theme="@style/DialogWhenLargeNoAnimation"
+ android:exported="false" />
+
+ <activity android:name=".UninstallerActivity"
+ android:configChanges="orientation|keyboardHidden|screenSize"
+ android:excludeFromRecents="true"
+ android:noHistory="true"
+ android:theme="@style/AlertDialogActivity">
+ <intent-filter android:priority="1">
+ <action android:name="android.intent.action.DELETE" />
+ <action android:name="android.intent.action.UNINSTALL_PACKAGE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:scheme="package" />
+ </intent-filter>
+ </activity>
+
+ <receiver android:name=".UninstallEventReceiver"
+ android:permission="android.permission.INSTALL_PACKAGES"
+ android:exported="true">
+ <intent-filter android:priority="1">
+ <action android:name="com.android.packageinstaller.ACTION_UNINSTALL_COMMIT" />
+ </intent-filter>
+ </receiver>
+
+ <activity android:name=".UninstallUninstalling"
+ android:excludeFromRecents="true"
+ android:theme="@style/AlertDialogActivity"
+ android:exported="false" />
+
+ <receiver android:name=".UninstallFinish"
+ android:exported="false" />
+
+ <activity android:name=".television.UninstallAppProgress"
+ android:configChanges="mnc|mnc|touchscreen|navigation|screenLayout|screenSize|smallestScreenSize|orientation|locale|keyboard|keyboardHidden|fontScale|uiMode|layoutDirection|density"
+ android:exported="false" />
+
+ <!-- Wearable Components -->
+ <service android:name=".wear.WearPackageInstallerService"
+ android:permission="com.google.android.permission.INSTALL_WEARABLE_PACKAGES"
+ android:exported="true"/>
+
+ <provider android:name=".wear.WearPackageIconProvider"
+ android:authorities="com.google.android.packageinstaller.wear.provider"
+ android:grantUriPermissions="true"
+ android:exported="true" />
+ </application>
+
+</manifest>
diff --git a/packages/PackageInstaller/CleanSpec.mk b/packages/PackageInstaller/CleanSpec.mk
new file mode 100644
index 0000000..b84e1b6
--- /dev/null
+++ b/packages/PackageInstaller/CleanSpec.mk
@@ -0,0 +1,49 @@
+# Copyright (C) 2007 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# If you don't need to do a full clean build but would like to touch
+# a file or delete some intermediate files, add a clean step to the end
+# of the list. These steps will only be run once, if they haven't been
+# run before.
+#
+# E.g.:
+# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
+# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
+#
+# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
+# files that are missing or have been moved.
+#
+# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
+# Use $(OUT_DIR) to refer to the "out" directory.
+#
+# If you need to re-do something that's already mentioned, just copy
+# the command and add it to the bottom of the list. E.g., if a change
+# that you made last week required touching a file and a change you
+# made today requires touching the same file, just copy the old
+# touch step and add it to the end of the list.
+#
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
+
+# For example:
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
+#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
+#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
+#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
diff --git a/packages/PackageInstaller/MODULE_LICENSE_APACHE2 b/packages/PackageInstaller/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/packages/PackageInstaller/MODULE_LICENSE_APACHE2
diff --git a/packages/PackageInstaller/NOTICE b/packages/PackageInstaller/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/packages/PackageInstaller/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/packages/PackageInstaller/OWNERS b/packages/PackageInstaller/OWNERS
new file mode 100644
index 0000000..252670a
--- /dev/null
+++ b/packages/PackageInstaller/OWNERS
@@ -0,0 +1,7 @@
+svetoslavganov@google.com
+moltmann@google.com
+toddke@google.com
+suprabh@google.com
+
+# For automotive related changes
+rogerxue@google.com
diff --git a/packages/PackageInstaller/res/anim/snackbar_enter.xml b/packages/PackageInstaller/res/anim/snackbar_enter.xml
new file mode 100644
index 0000000..96bf4d2
--- /dev/null
+++ b/packages/PackageInstaller/res/anim/snackbar_enter.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="100%" android:toYDelta="0"
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:duration="250"/>
+ <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:interpolator="@android:interpolator/decelerate_quint"
+ android:duration="250" />
+</set>
diff --git a/packages/PackageInstaller/res/anim/snackbar_exit.xml b/packages/PackageInstaller/res/anim/snackbar_exit.xml
new file mode 100644
index 0000000..9aee177
--- /dev/null
+++ b/packages/PackageInstaller/res/anim/snackbar_exit.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* Copyright 2015, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shareInterpolator="false">
+ <translate android:fromYDelta="0" android:toYDelta="100%"
+ android:interpolator="@android:interpolator/accelerate_quint"
+ android:duration="250"/>
+ <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+ android:interpolator="@android:interpolator/accelerate_quint"
+ android:duration="250"/>
+</set>
diff --git a/packages/PackageInstaller/res/drawable/ic_android_92.xml b/packages/PackageInstaller/res/drawable/ic_android_92.xml
new file mode 100644
index 0000000..1d3791c
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_android_92.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="92dp"
+ android:height="92dp"
+ android:viewportWidth="92.0"
+ android:viewportHeight="92.0">
+ <path
+ android:fillColor="#000000"
+ android:pathData="m23,69c0,2.11 1.72,3.83 3.83,3.83h3.83v13.42c0,3.18 2.57,5.75 5.75,5.75 3.18,0 5.75,-2.57 5.75,-5.75L42.17,72.83h7.67v13.42c0,3.18 2.57,5.75 5.75,5.75 3.18,0 5.75,-2.57 5.75,-5.75L61.33,72.83h3.83c2.11,0 3.83,-1.72 3.83,-3.83L69,30.67L23,30.67L23,69zM13.42,30.67c-3.18,0 -5.75,2.57 -5.75,5.75v26.83c0,3.18 2.57,5.75 5.75,5.75 3.18,0 5.75,-2.57 5.75,-5.75L19.17,36.42c0,-3.18 -2.57,-5.75 -5.75,-5.75zM78.58,30.67c-3.18,0 -5.75,2.57 -5.75,5.75v26.83c0,3.18 2.57,5.75 5.75,5.75 3.18,0 5.75,-2.57 5.75,-5.75L84.33,36.42c0,-3.18 -2.57,-5.75 -5.75,-5.75zM59.53,8.28 L64.53,3.28c0.75,-0.75 0.75,-1.95 0,-2.7 -0.75,-0.75 -1.95,-0.75 -2.7,0L56.16,6.23C53.09,4.72 49.66,3.84 46,3.84c-3.68,0 -7.13,0.88 -10.22,2.41L30.09,0.56c-0.75,-0.75 -1.95,-0.75 -2.7,0 -0.75,0.75 -0.75,1.95 0,2.7l5.02,5.02C26.72,12.48 23,19.23 23,26.84h46c0,-7.63 -3.74,-14.37 -9.47,-18.55zM38.33,19.17h-3.83v-3.83h3.83v3.83zM57.5,19.17h-3.83v-3.83h3.83v3.83z"/>
+</vector>
diff --git a/packages/PackageInstaller/res/drawable/ic_done_92.xml b/packages/PackageInstaller/res/drawable/ic_done_92.xml
new file mode 100644
index 0000000..185b274
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_done_92.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="92dp"
+ android:height="92dp"
+ android:viewportWidth="92.0"
+ android:viewportHeight="92.0">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M34.5,61.99 L18.51,46 13.09,51.42 34.5,72.83l46,-46 -5.42,-5.42z"/>
+</vector>
diff --git a/packages/PackageInstaller/res/drawable/ic_error.xml b/packages/PackageInstaller/res/drawable/ic_error.xml
new file mode 100644
index 0000000..28612a1
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_error.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"
+ android:fillColor="#000000"/>
+</vector>
diff --git a/packages/PackageInstaller/res/drawable/ic_file_download.xml b/packages/PackageInstaller/res/drawable/ic_file_download.xml
new file mode 100644
index 0000000..7ea91f5
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_file_download.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z" />
+ <path
+ android:pathData="M0 0h24v24H0z" />
+</vector>
diff --git a/packages/PackageInstaller/res/drawable/ic_lock.xml b/packages/PackageInstaller/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..396bd98
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_lock.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <path
+ android:pathData="M0 0h48v48H0z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M36 16h-2v-4c0-5.52-4.48-10-10-10S14 6.48 14 12v4h-2c-2.21 0-4 1.79-4 4v20c0
+2.21 1.79 4 4 4h24c2.21 0 4-1.79 4-4V20c0-2.21-1.79-4-4-4zM24 34c-2.21
+0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm6.2-18H17.8v-4c0-3.42 2.78-6.2
+6.2-6.2 3.42 0 6.2 2.78 6.2 6.2v4z" />
+</vector>
diff --git a/packages/PackageInstaller/res/drawable/ic_remove.xml b/packages/PackageInstaller/res/drawable/ic_remove.xml
new file mode 100644
index 0000000..dd46eda
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_remove.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM17,13L7,13v-2h10v2z"
+ android:fillColor="#000000"/>
+</vector>
diff --git a/packages/PackageInstaller/res/drawable/ic_report_problem_92.xml b/packages/PackageInstaller/res/drawable/ic_report_problem_92.xml
new file mode 100644
index 0000000..c90a33e
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_report_problem_92.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="92dp"
+ android:height="92dp"
+ android:viewportWidth="92.0"
+ android:viewportHeight="92.0">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M2,84H90L46,8 2,84zM50,72h-8v-8h8v8zM50,56H42V40h8v16z"/>
+</vector>
diff --git a/packages/PackageInstaller/res/drawable/ic_settings_multiuser.xml b/packages/PackageInstaller/res/drawable/ic_settings_multiuser.xml
new file mode 100644
index 0000000..b24a5d4
--- /dev/null
+++ b/packages/PackageInstaller/res/drawable/ic_settings_multiuser.xml
@@ -0,0 +1,25 @@
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24.0dp"
+ android:height="24.0dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"
+ android:tint="?android:attr/colorAccent">
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M12.0,12.0c2.21,0.0 4.0,-1.79 4.0,-4.0s-1.79,-4.0 -4.0,-4.0 -4.0,1.79 -4.0,4.0 1.79,4.0 4.0,4.0zm0.0,2.0c-2.67,0.0 -8.0,1.34 -8.0,4.0l0.0,2.0l16.0,0.0l0.0,-2.0c0.0,-2.66 -5.33,-4.0 -8.0,-4.0z"/>
+</vector>
diff --git a/packages/PackageInstaller/res/layout-television/app_details.xml b/packages/PackageInstaller/res/layout-television/app_details.xml
new file mode 100644
index 0000000..86923c5
--- /dev/null
+++ b/packages/PackageInstaller/res/layout-television/app_details.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<!--
+Defines the layout of the application snippet that appears on top of the
+installation screens
+-->
+<!-- The snippet about the application - title, icon -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/app_snippet"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:orientation="horizontal">
+
+ <ImageView android:id="@+id/app_icon"
+ android:layout_marginLeft="16dp"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_gravity="center_vertical"
+ android:scaleType="fitCenter" />
+
+ <TextView android:id="@+id/app_name"
+ android:layout_gravity="center_vertical"
+ android:layout_marginLeft="32dp"
+ android:layout_marginRight="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/titleTextStyle"
+ android:singleLine="true"
+ android:ellipsize="end" />
+
+</LinearLayout>
+
diff --git a/packages/PackageInstaller/res/layout-television/uninstall_progress.xml b/packages/PackageInstaller/res/layout-television/uninstall_progress.xml
new file mode 100644
index 0000000..e24f63b
--- /dev/null
+++ b/packages/PackageInstaller/res/layout-television/uninstall_progress.xml
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <include layout="@layout/app_details"
+ android:id="@+id/app_snippet"/>
+
+ <LinearLayout android:id="@+id/progress_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:padding="16dp">
+
+ <ImageView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:src="@drawable/ic_android_92"
+ android:tint="@color/bigIconColor"
+ android:contentDescription="@null" />
+
+ <ProgressBar android:id="@+id/progress_bar"
+ android:layout_width="250dp"
+ android:layout_height="wrap_content"
+ android:indeterminate="true"
+ style="?android:attr/progressBarStyleHorizontal">
+ </ProgressBar>
+
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/uninstalling"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </LinearLayout>
+
+ <!-- Status view is shown after progress view is removed -->
+ <ScrollView android:id="@+id/status_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:visibility="gone"
+ android:padding="16dp">
+
+ <TextView android:id="@+id/status_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="start"
+ android:textAppearance="?android:attr/textAppearanceMedium"/>
+ </ScrollView>
+
+ <LinearLayout android:id="@+id/ok_panel"
+ style="?android:attr/buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:measureWithLargestChild="true"
+ android:visibility="gone"
+ android:padding="8dip">
+
+ <!-- spacer to push buttons to the right -->
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/device_manager_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:text="@string/manage_device_administrators"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ <Button android:id="@+id/users_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:text="@string/manage_users"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ <Button android:id="@+id/ok_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/ok"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/PackageInstaller/res/layout/install_confirm.xml b/packages/PackageInstaller/res/layout/install_confirm.xml
new file mode 100644
index 0000000..6be46fc
--- /dev/null
+++ b/packages/PackageInstaller/res/layout/install_confirm.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout android:id="@+id/app_snippet"
+ android:background="?android:attr/colorPrimary"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:orientation="horizontal"
+ android:elevation="@dimen/headerElevation"
+ android:gravity="center_vertical">
+
+ <ImageView android:id="@+id/app_icon"
+ android:layout_marginStart="16dp"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_file_download" />
+
+ <TextView android:id="@+id/app_name"
+ android:layout_marginStart="32dp"
+ android:layout_marginEnd="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/titleTextStyle"
+ android:singleLine="true"
+ android:text="@string/app_name_unknown"
+ android:ellipsize="end" />
+
+ </LinearLayout>
+
+ <ScrollView android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:padding="16dip">
+
+ <TextView android:id="@+id/install_confirm_question"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </ScrollView>
+
+ <LinearLayout style="?android:attr/buttonBarStyle"
+ android:background="?android:attr/colorBackground"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="8dp"
+ android:measureWithLargestChild="true">
+
+ <!-- spacer to push buttons to the right -->
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/cancel_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/cancel"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ <Button android:id="@+id/ok_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/install"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/PackageInstaller/res/layout/install_failed.xml b/packages/PackageInstaller/res/layout/install_failed.xml
new file mode 100644
index 0000000..d000ee9
--- /dev/null
+++ b/packages/PackageInstaller/res/layout/install_failed.xml
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout android:id="@+id/app_snippet"
+ android:background="?android:attr/colorPrimary"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:orientation="horizontal"
+ android:elevation="@dimen/headerElevation"
+ android:gravity="center_vertical">
+
+ <ImageView android:id="@+id/app_icon"
+ android:layout_marginStart="16dp"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:scaleType="fitCenter" />
+
+ <TextView android:id="@+id/app_name"
+ android:layout_marginStart="32dp"
+ android:layout_marginEnd="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/titleTextStyle"
+ android:singleLine="true"
+ android:ellipsize="end" />
+
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/simple_status_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip">
+
+ <ImageView android:id="@+id/center_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:src="@drawable/ic_report_problem_92"
+ android:tint="@color/bigIconColor"
+ android:contentDescription="@null" />
+
+ <TextView android:id="@+id/simple_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/buttons_panel"
+ style="?android:attr/buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:measureWithLargestChild="true"
+ android:padding="8dip">
+
+ <!-- spacer to push button to the right -->
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/done_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/done"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ </LinearLayout>
+
+</LinearLayout>
+
+
diff --git a/packages/PackageInstaller/res/layout/install_installing.xml b/packages/PackageInstaller/res/layout/install_installing.xml
new file mode 100644
index 0000000..a043a01
--- /dev/null
+++ b/packages/PackageInstaller/res/layout/install_installing.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout android:id="@+id/app_snippet"
+ android:background="?android:attr/colorPrimary"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:orientation="horizontal"
+ android:elevation="@dimen/headerElevation"
+ android:gravity="center_vertical">
+
+ <ImageView
+ android:id="@+id/app_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginStart="16dp"
+ android:scaleType="fitCenter" />
+
+ <TextView
+ android:id="@+id/app_name"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="32dp"
+ android:layout_marginEnd="16dp"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/titleTextStyle" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip">
+
+ <ImageView
+ android:layout_width="92dp"
+ android:layout_height="92dp"
+ android:layout_marginBottom="12dp"
+ android:contentDescription="@null"
+ android:tint="@color/bigIconColor"
+ android:src="@drawable/ic_file_download" />
+
+ <ProgressBar
+ android:id="@+id/progress_bar"
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_width="250dp"
+ android:layout_height="wrap_content"
+ android:indeterminate="false" />
+
+ <TextView
+ android:id="@+id/center_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/installing"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/buttons_panel"
+ style="?android:attr/buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:measureWithLargestChild="true"
+ android:orientation="horizontal"
+ android:padding="8dip">
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button
+ android:id="@+id/cancel_button"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="2"
+ android:text="@string/cancel" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/packages/PackageInstaller/res/layout/install_staging.xml b/packages/PackageInstaller/res/layout/install_staging.xml
new file mode 100644
index 0000000..e3022e7
--- /dev/null
+++ b/packages/PackageInstaller/res/layout/install_staging.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<!--
+ Defines the layout of the splash screen that displays the security
+ settings required for an application and requests the confirmation of the
+ user before it is installed.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <!-- title bar -->
+ <LinearLayout android:id="@+id/app_snippet"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:background="?android:attr/colorPrimary"
+ android:elevation="@dimen/headerElevation"
+ android:gravity="center_vertical"
+ android:orientation="horizontal">
+
+ <ImageView android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_marginLeft="16dp"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_file_download"
+ android:tint="?android:attr/colorAccent" />
+
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="32dp"
+ android:layout_marginRight="16dp"
+ android:ellipsize="end"
+ android:singleLine="true"
+ android:text="@string/app_name_unknown"
+ android:textAppearance="?android:attr/titleTextStyle" />
+
+ </LinearLayout>
+
+ <!-- content -->
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip">
+
+ <ImageView
+ android:layout_width="92dp"
+ android:layout_height="92dp"
+ android:scaleType="fitCenter"
+ android:layout_marginBottom="12dp"
+ android:contentDescription="@null"
+ android:tint="@color/bigIconColor"
+ android:src="@drawable/ic_file_download" />
+
+ <ProgressBar
+ style="?android:attr/progressBarStyleHorizontal"
+ android:layout_width="250dp"
+ android:layout_height="wrap_content"
+ android:indeterminate="true" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/message_staging"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </LinearLayout>
+
+ <!-- Bottom buttons -->
+ <LinearLayout style="?android:attr/buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:padding="8dp">
+
+ <!-- spacer to push button to the right -->
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/cancel_button"
+ style="?android:attr/buttonBarButtonStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:maxLines="2"
+ android:text="@string/cancel" />
+
+ </LinearLayout>
+
+</LinearLayout>
+
+
diff --git a/packages/PackageInstaller/res/layout/install_success.xml b/packages/PackageInstaller/res/layout/install_success.xml
new file mode 100644
index 0000000..fee6bed
--- /dev/null
+++ b/packages/PackageInstaller/res/layout/install_success.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout android:id="@+id/app_snippet"
+ android:background="?android:attr/colorPrimary"
+ android:layout_width="match_parent"
+ android:layout_height="?android:attr/actionBarSize"
+ android:orientation="horizontal"
+ android:elevation="@dimen/headerElevation"
+ android:gravity="center_vertical">
+
+ <ImageView android:id="@+id/app_icon"
+ android:layout_marginStart="16dp"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:scaleType="fitCenter" />
+
+ <TextView android:id="@+id/app_name"
+ android:layout_marginStart="32dp"
+ android:layout_marginEnd="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/titleTextStyle"
+ android:singleLine="true"
+ android:ellipsize="end" />
+
+ </LinearLayout>
+
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center"
+ android:orientation="vertical"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip">
+
+ <ImageView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="12dp"
+ android:src="@drawable/ic_done_92"
+ android:tint="@color/bigIconColor"
+ android:contentDescription="@null" />
+
+ <TextView android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:text="@string/install_done"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ </LinearLayout>
+
+ <LinearLayout style="?android:attr/buttonBarStyle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:measureWithLargestChild="true"
+ android:padding="8dip">
+
+ <!-- spacer to push buttons to the right -->
+ <View android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button android:id="@+id/done_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/done"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ <Button android:id="@+id/launch_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/launch"
+ android:maxLines="2"
+ style="?android:attr/buttonBarButtonStyle" />
+
+ </LinearLayout>
+
+</LinearLayout>
+
+
diff --git a/packages/PackageInstaller/res/values-af-television/strings.xml b/packages/PackageInstaller/res/values-af-television/strings.xml
new file mode 100644
index 0000000..32cf00f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-af-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Weier en moenie weer vra nie"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Jy kan dit later verander in Instellings > Programme"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Wys stelselprogramme"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Programtoestemmings"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Programtoestemmings"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g>toestemmings"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Bykomende toestemmings"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g>toestemmings"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-af-watch/strings.xml b/packages/PackageInstaller/res/values-af-watch/strings.xml
new file mode 100644
index 0000000..a62540f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-af-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Weier; moenie weer vra nie"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Wys stelselprogramme"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Onveranderbaar"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ja"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Kanselleer"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml
new file mode 100644
index 0000000..0d41c18
--- /dev/null
+++ b/packages/PackageInstaller/res/values-af/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pakketinstalleerder"</string>
+ <string name="next" msgid="3057143178373252333">"Volgende"</string>
+ <string name="install" msgid="5896438203900042068">"Installeer"</string>
+ <string name="done" msgid="3889387558374211719">"Klaar"</string>
+ <string name="cancel" msgid="8360346460165114585">"Kanselleer"</string>
+ <string name="installing" msgid="8613631001631998372">"Installeer tans…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installeer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+ <string name="install_done" msgid="3682715442154357097">"Program geïnstalleer."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Wil jy hierdie program installeer? Dit sal kan ingaan by:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Wil jy hierdie program installeer? Dit vereis nie enige spesiale toegang nie."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Wil jy \'n opdatering vir die bestaande program installeer? Jou bestaande data sal nie verlore gaan nie. Die opgedateerde program sal kan ingaan by:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Wil jy \'n opdatering vir hierdie ingeboude program installeer? Jou bestaande data sal nie verlore gaan nie. Die opgedateerde program sal kan ingaan by:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Wil jy \'n opdatering na hierdie bestaande program installeer? Jou bestaande data sal nie verlore raak nie. Dit vereis nie enige spesiale toegang nie."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Wil jy \'n opdatering na hierdie ingeboude program installeer? Jou bestaande data sal nie verlore raak nie. Dit vereis nie enige spesiale toegang nie."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Program nie geïnstalleer nie."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Die installering van die pakket is geblokkeer."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Program is nie geïnstalleer nie omdat pakket met \'n bestaande pakket bots."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Program is nie geïnstalleer nie omdat dit nie met jou tablet versoenbaar is nie."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Hierdie program is nie met jou TV versoenbaar nie."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Program is nie geïnstalleer nie omdat dit nie met jou foon versoenbaar is nie."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Program is nie geïnstalleer nie omdat pakket ongeldig blyk te wees."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou tablet geïnstalleer word nie."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou TV geïnstalleer word nie."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou foon geïnstalleer word nie."</string>
+ <string name="launch" msgid="4826921505917605463">"Open"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Jou administrateur laat nie toe dat programme wat by onbekende bronne verkry is, geïnstalleer word nie"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Hierdie gebruiker kan nie onbekende programme installeer nie"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Hierdie gebruiker word nie toegelaat om programme te installeer nie"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Bestuur programme"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Geen spasie oor nie"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie geïnstalleer word nie. Maak \'n bietjie plek en probeer weer."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Program nie gevind nie"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Die program is nie in die lys van geïnstalleerde programme gevind nie."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nie toegelaat nie"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Die huidige gebruiker mag nie hierdie deïnstallering uitvoer nie."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fout"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Program kon nie gedeïnstalleer word nie."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Deïnstalleer program"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Deïnstalleer opdatering"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is deel van die volgende program:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Wil jy hierdie program deïnstalleer?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Wil jy hierdie program vir "<b>"alle"</b>" gebruikers deïnstalleer? Die program en sy data sal vir "<b>"alle"</b>" gebruikers op hierdie toestel verwyder word."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Wil jy hierdie program vir die gebruiker <xliff:g id="USERNAME">%1$s</xliff:g> deïnstalleer?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word. Dit beïnvloed alle gebruikers van hierdie toestel, insluitend dié met werkprofiele."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Voer tans deïnstallerings uit"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislukte installerings"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Deïnstalleer tans…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Deïnstalleer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Deïnstallering klaar."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Het <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> gedeïnstalleer"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Deïnstallasie onsuksesvol."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Kon nie <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deïnstalleer nie."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Kan nie aktiewe toesteladministrasieprogram deïnstalleer nie"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kan nie aktiewe toesteladministrasieprogram vir <xliff:g id="USERNAME">%1$s</xliff:g> deïnstalleer nie"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Dié program word vereis vir sommige gebruikers of profiele en is vir ander gedeïnstalleer"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Hierdie program is nodig vir jou profiel en kan nie gedeïnstalleer word nie."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Jou toesteladministrateur vereis die program; dit kan nie deïnstalleer word nie."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Bestuur toesteladministrasieprogramme"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Bestuur gebruikers"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie deïnstalleer word nie."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kon nie die pakket ontleed nie."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nuut"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privaatheid"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Toesteltoegang"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Hierdie opdatering vereis geen nuwe toestemmings nie."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Weier"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Meer inligting"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Weier in elk geval"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> van <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Laat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toe om <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Laat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> altyd toe om <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Net terwyl program gebruik word"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Altyd"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Weier en moenie weer vra nie"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> is gedeaktiveer"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"alles is gedeaktiveer"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"geen is gedeaktiveer nie"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Laat toe"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Programme"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Programtoestemmings"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Moenie weer vra nie"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Geen toestemmings nie"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Bykomende toestemmings"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Maak programinligting oop"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Nog <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Nog <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Hierdie program is vir \'n ouer weergawe van Android ontwerp. As toestemming geweier word, kan dit veroorsaak dat dit nie meer soos beplan funksioneer nie."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"voer \'n onbekende handeling uit"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> uit <xliff:g id="COUNT_1">%2$d</xliff:g> programme toegelaat"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Wys stelsel"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Versteek stelsel"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Geen programme nie"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Ligginginstellings"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is \'n verskaffer van liggingdienste vir hierdie toestel. Liggingtoegang kan vanuit ligginginstellings verander word."</string>
+ <string name="system_warning" msgid="7103819124542305179">"As jy hierdie toestemming weier, sal basiese kenmerke van jou toestel dalk nie meer soos bedoel werk nie."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Afgedwing deur beleid"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Agtergrondtoegang is gedeaktiveer volgens beleid"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Agtergrondtoegang is geaktiveer volgens beleid"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Voorgrondtoegang is geaktiveer volgens beleid"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Beheer deur administrateur"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Altyd"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Net as program gebruik word"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nooit"</string>
+ <string name="loading" msgid="7811651799620593731">"Laai tans …"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Alle toestemmings"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Ander programvermoëns"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Toestemmingsversoek"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Skermoorlegger bespeur"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Om hierdie toestemminginstelling te verander, moet jy eers die skermoorlegger by Instellings > Programme afskakel"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Maak instellings oop"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Installeer- en deïnstalleerhandelinge word nie in Wear gesteun nie."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Kies waartoe <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang mag kry"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> is opgedateer. Kies waartoe hierdie program toegang mag kry."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Kanselleer"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Gaan voort"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nuwe toestemmings"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Huidige toestemmings"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Voer tans program uit …"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Onbekend"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Jou tablet word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Jou TV word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Jou foon word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Jou foon en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou foon of verlies van data wat uit sy gebruik kan spruit."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Jou tablet en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou tablet of verlies van data wat uit sy gebruik kan spruit."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Jou TV en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou TV of verlies van data wat uit sy gebruik kan spruit."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Gaan voort"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Instellings"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installeer/deïnstalleer Wear-programme"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-am-television/strings.xml b/packages/PackageInstaller/res/values-am-television/strings.xml
new file mode 100644
index 0000000..e4f23c1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-am-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"አይቀበሉና እንደገና ይጠይቁ"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ይሄንን በኋላ ላይ በቅንብሮችና መተግበሪያዎች ውስጥ ሊቀይሩት ይችላሉ"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"የስርዓት መተግበሪያዎችን አሳይ"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"የመተግበሪያ ፈቃዶች"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"የመተግበሪያ ፈቃዶች"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> ፈቃዶች"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"ተጨማሪ ፈቃዶች"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> ፈቃዶች"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-am-watch/strings.xml b/packages/PackageInstaller/res/values-am-watch/strings.xml
new file mode 100644
index 0000000..1b01ddd
--- /dev/null
+++ b/packages/PackageInstaller/res/values-am-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ከልክል፣ ዳግም አትጠይቅ"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"የስርዓት መተግበሪያዎችን አሳይ"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ሊለወጥ አይችልም"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"አዎ"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"ይቅር"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml
new file mode 100644
index 0000000..d4c5076
--- /dev/null
+++ b/packages/PackageInstaller/res/values-am/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"ጥቅል ጫኝ"</string>
+ <string name="next" msgid="3057143178373252333">"ቀጣይ"</string>
+ <string name="install" msgid="5896438203900042068">"ጫን"</string>
+ <string name="done" msgid="3889387558374211719">"ተከናውኗል"</string>
+ <string name="cancel" msgid="8360346460165114585">"ይቅር"</string>
+ <string name="installing" msgid="8613631001631998372">"በመጫን ላይ…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በመጫን ላይ…"</string>
+ <string name="install_done" msgid="3682715442154357097">"መተግበሪያ ተጭኗል፡፡"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ይህንን መተግበሪያ መጫን ይፈልጋሉ? ወደዚህ መዳረሻ ያገኛል፦"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ይህንን መተግበሪያ መጫን ይፈልጋሉ? ምንም የተለየ መዳረሻ አይጠይቅም።"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"ለእዚህ ነባር መተግበሪያ ማዘመኛ መጫን ይፈልጋሉ? የነበረው ውሂብህ አይጠፋም። የዘመነው መተግበሪያ ወደዚህ መዳረሻ ያገኛል፦"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ለእዚህ አብሮ ለተሰራ መተግበሪያ ማዘመኛ መጫን ይፈልጋሉ? የነበረው ውሂብዎ አይጠፋም። የዘመነው መተግበሪያ ወደዚህ መዳረሻ ያገኛል፦"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ለዚህ ነባር መተግበሪያ ዝማኔ መጫን ይፈልጋሉ? ነባር ውሂብዎ አይጠፉም። ምንም የተለየ መዳረሻ አይፈልግም።"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ለዚህ አብሮ ለተሰራ መተግበሪያ ዝማኔ መጫን ይፈልጋሉ? ነባር ውሂብዎ አይጠፉም። ምንም የተለየ መዳረሻ አይፈልግም።"</string>
+ <string name="install_failed" msgid="6579998651498970899">"ትግበራ አልተጫነም።"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ጥቅሉ እንዳይጫን ታግዷል።"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"እንደ ጥቅል ያልተጫነ መተግበሪያ ከነባር ጥቅል ጋር ይጋጫል።"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"እንደ መተግበሪያ ያልተጫነ መተግበሪያ ከጡባዊዎ ጋር ተኳሃኝ አይደለም።"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ይሄ መተግበሪያ ከእርስዎ ቴሌቪዥን ጋር ተኳሃኝ አይደለም።"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"እንደ መተግበሪያ ያልተጫነ መተግበሪያ ከስልክዎ ጋር ተኳሃኝ አይደለም።"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"እንደ ጥቅል ያልተጫነ መተግበሪያ ልክ ያልሆነ ይመስላል።"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> በዚህ ስልክ ላይ መጫን አልተቻለም።"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ ቴሌቪዥን ላይ ሊጫን አልቻለም።"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>በዚህ ስልክ ላይ መጫን አልተቻለም።"</string>
+ <string name="launch" msgid="4826921505917605463">"ክፈት"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"የእርስዎ አስተዳዳሪ ካልታወቁ ምንጮች የመጡ መተግበሪያዎች እንዲጫኑ አይፈቅድም"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ያልታወቁ መተግበሪያዎች በዚህ ተጠቃሚ ሊጫኑ አይችሉም"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ይህ ተጠቃሚ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም"</string>
+ <string name="ok" msgid="3468756155452870475">"እሺ"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"መተግበሪያዎች አስተዳድር"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ቦታ ሞልቷል"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>ለመጫን አልቻለም። ትንሽ ቦታ አስለቅቅ እና እንደገና ሞክር፡፡"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ትግበራ አልተገኘም"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"መተግበሪያው በተጫኑ መተግበሪያዎች ዝርዝር ውስጥ አልተገኘም።"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"አይፈቀድም"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"አሁን ያለው ተጠቃሚ ይህን ማራገፍ ሥራ እንዲያከናውን አይፈቀድለትም።"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ስሕተት"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"መተግበሪያ ሊራገፍ አልተቻለም"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ትግበራ አራግፍ"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"ማዘመን አራግፍ"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>የሚከተለው ትግበራ አካል ነው፡"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ይሄን መተግበሪያ ማራገፍ ይፈልጋሉ?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ይህን መተግበሪያ "<b>"ለሁሉም"</b>" ተጠቃሚዎች መጫን ይፈልጋሉ? መተግበሪያው እና ውሂቡ በመሣሪያው ላይ ካሉ "<b>"ሁሉም"</b>" ተጠቃሚዎች ይሰረዛሉ።"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"ይህን መተግበሪያ ለተጠቃሚ <xliff:g id="USERNAME">%1$s</xliff:g> ማራገፍ ይፈልጋሉ?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ይህ መተግበሪያ በፋብሪክው ስሪት ይተካ? ሁሉም ውሂብ ይወገዳል።"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ይህ መተግበሪያ በፋብሪክው ስሪት ይተካ? ሁሉም ውሂብ ይወገዳል። እነዚያን የሥራ መገለጫዎች ያላቸውን ጨምሮ ሁሉንም በዚህ መሣሪያ ላይ ባሉ ተጠቃሚዎች ላይ ተጽዕኖ ያሳርፍባቸዋል።"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"በማሄድ ላይ ያሉ ማራገፎች"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ያልተሳኩ ማራገፎች"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"ባለመጫንላይ"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በማራገፍ ላይ…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"አራግፍ ተጠናቋል"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ተራግፏል"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ማራገፍ አልተሳካም፡፡"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን ማራገፍ ስኬታማ አልነበረም።"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ገባሪ የመሣሪያ አስተዳደር መተግበሪያን ማራገፍ አይቻልም"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"ለ<xliff:g id="USERNAME">%1$s</xliff:g> ገባሪ የመሣሪያ አስተዳደር መተግበሪያን ማራገፍ አይቻልም"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ይህ መተግበሪያ ለአንዳንድ ተጠቃሚዎች ወይም መገለጫዎች ያስፈልጋል እና ለሌሎች ተራግፏል"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ይህ መተግበሪያ ለእርስዎ መገለጫዎ ያስፈልጋል እና ሊራገፍ አይችልም።"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ይህ መተግበሪያ በመሣሪያዎ አስተዳዳሪ የሚፈለግ እና ሊራገፍ የማይችል ነው።"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"የመሣሪያ አስተዳደር መተግበሪያዎችን ያስተዳድሩ"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ተጠቃሚዎችን ያስተዳድሩ"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>ማራገፍ አልተቻለም"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"አካታቹን መተንተን ችግር ነበረ።"</string>
+ <string name="newPerms" msgid="6039428254474104210">"አዲስ"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ሁሉም"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ግላዊነት"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"የመሳሪያ መዳረሻ"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ይህ ዝማኔ ምንም አዲስ ፈቃድ አያስፈልገውም።"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ከልክል"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ተጨማሪ መረጃ"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ለማንኛውም ከልክል"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ከ<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g> እንዲከናወን ይፈቀድለት?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"ሁልጊዜ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ወደ <xliff:g id="ACTION">%2$s</xliff:g> ይፈቀድ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"መተግበሪያን በመጠቀም ላይ ሲኮን ብቻ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ሁልጊዜ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"አትቀበል እና እንደገና አትጠይቅ"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ተሰናክሏል"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"ሁሉም ተሰናክሏል"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ምንም አልተሰናከለም"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ፍቀድ"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"መተግበሪያዎች"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"የመተግበሪያ ፈቃዶች"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ዳግም አትጠይቅ"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ምንም ፍቃዶች የሉም"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"ተጨማሪ ፈቃዶች"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"የመተግበሪያ መረጃን ክፈት"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተጨማሪ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተጨማሪ</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ይህ መተግበሪያ ለAndroid አሮጌ ስሪት የተነደፈ ነበር። ፈቃድ መከልከል እንደሚፈለገው ከእንግዲህ እንዳይሰራ ሊያደርገው ይችላል።"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ያልታወቀ እርምጃ ያከናውናል"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> ከ<xliff:g id="COUNT_1">%2$d</xliff:g> መተግበሪያዎች ተፈቅዶላቸዋል"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"ስርዓትን አሳይ"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"ስርዓትን ደብቅ"</string>
+ <string name="no_apps" msgid="1965493419005012569">"ምንም መተግበሪያዎች የሉም"</string>
+ <string name="location_settings" msgid="1774875730854491297">"የአካባቢ ቅንብሮች"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> የዚህ መሳሪያ አካባቢ አገልግሎቶች አቅራቢ ነው። የአካባቢ መዳረሻ ከአካባቢ ቅንብሮች ሊሻሻል ይችላል።"</string>
+ <string name="system_warning" msgid="7103819124542305179">"ይህን ፍቃድ ከከለከሉ የመሳሪያዎ መሰረታዊ ባህሪያት ከዚህ በኋላ እንደተፈለገው ላይሰሩ ይችላሉ።"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"በመመሪያ ተፈጻሚ የሆነ"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"የጀርባ መዳረሻ በመመሪያ ተሰናክሏል"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"የጀርባ መዳረሻ በመመሪያ ነቅቷል"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"የፊት መዳረሻ በመመሪያ ነቅቷል"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"በአስተዳዳሪ ቁጥጥር የሚደረግበት"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ዘወትር"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"መተግበሪያን በስራ ላይ ሲሆን ብቻ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"በጭራሽ"</string>
+ <string name="loading" msgid="7811651799620593731">"በመጫን ላይ…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"ሁሉም ፍቃዶች"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"ሌሎች የመተግበሪያ ችሎታዎች"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"የፍቃድ ጥያቄ"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"የማያ ገጽ ተደራቢ ተገኝቷል"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ይህን የፍቃድ ቅንብር ለመቀየር መጀመሪያ የማያ ገጽ ተደራቢውን ከቅንብሮች > መተግበሪያዎች ማጥፋት አለብዎ"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ቅንብሮችን ክፈት"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"በWear ላይ የመጫን/ማራገፍ እርምጃዎች አይደገፉም።"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ምን መድረስ እንደሚችል ይምረጡ"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ተዘምኗል። ይህ መተግበሪያ ምን መድረስ እንደሚችል ይምረጡ።"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"ይቅር"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ቀጥል"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"አዲስ ፍቃዶች"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"የአሁኖቹ ፍቃዶች"</string>
+ <string name="message_staging" msgid="6151794817691100003">"መተግበሪያን በማዘጋጀት ላይ…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"ያልታወቀ"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ለእርስዎ ደህንነት ሲባል የእርስዎ ጡባዊ ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ለእርስዎ ደህንነት ሲባል የእርስዎ ቴሌቪዥን ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ለእርስዎ ደህንነት ሲባል የእርስዎ ስልክ ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"የእርስዎ ስልክ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይልበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ስልክ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"የእርስዎ ጡባዊ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ጡባዊ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"የእርስዎ ቴሌቪዥን እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ቴሌቪዥን ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ቀጥል"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ቅንብሮች"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"የWear መተግበሪያዎችን መጫን/ማራገፍ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ar-television/strings.xml b/packages/PackageInstaller/res/values-ar-television/strings.xml
new file mode 100644
index 0000000..9297b88
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ar-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"رفض وعدم طرح السؤال مرة أخرى"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"يمكنك تغيير ذلك لاحقًا من خلال الإعدادات > التطبيقات"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"عرض تطبيقات النظام"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"أذونات التطبيق"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"أذونات التطبيق"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"أذونات <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"أذونات إضافية"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"أذونات <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ar-watch/strings.xml b/packages/PackageInstaller/res/values-ar-watch/strings.xml
new file mode 100644
index 0000000..19930ea
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ar-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"الرفض وعدم السؤال مرة أخرى"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"عرض تطبيقات النظام"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"لا يمكن التغيير"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"نعم"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"إلغاء"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
new file mode 100644
index 0000000..613481e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"أداة تثبيت الحزم"</string>
+ <string name="next" msgid="3057143178373252333">"التالي"</string>
+ <string name="install" msgid="5896438203900042068">"تثبيت"</string>
+ <string name="done" msgid="3889387558374211719">"تم"</string>
+ <string name="cancel" msgid="8360346460165114585">"إلغاء"</string>
+ <string name="installing" msgid="8613631001631998372">"جارٍ التثبيت..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"جارٍ تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"تم تثبيت التطبيق."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"هل تريد تثبيت هذا التطبيق؟ سيكون بإمكانه الدخول إلى:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"هل تريد تثبيت هذا التطبيق؟ إنه لا يتطلب أي دخول خاص."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"هل تريد تثبيت تحديث لهذا التطبيق الحالي؟ لن تفقد بياناتك الحالية. سيكون بإمكان التطبيق المحدّث الدخول إلى:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"هل تريد تثبيت تحديث لهذا التطبيق المضمن؟ لن تفقد بياناتك الحالية. سيكون بإمكان التطبيق المحدّث الدخول إلى:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"هل تريد تثبيت تحديث لهذا التطبيق الحالي؟ لن يتم فقد بياناتك الحالية. كما أنه لا يتطلب أي دخول خاص."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"هل تريد تثبيت تحديث لهذا التطبيق المضمن؟ لن يتم فقد بياناتك الحالية. كما أنه لا يتطلب أي دخول خاص."</string>
+ <string name="install_failed" msgid="6579998651498970899">"التطبيق ليس مثبتًا."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"تم حظر تثبيت الحزمة."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"لم يتم تثبيت التطبيق لأن حزمة التثبيت تتعارض مع حزمة حالية."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"لم يتم تثبيت التطبيق لأنه ليس متوافقًا مع جهازك اللوحي."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"هذا التطبيق لا يتوافق مع جهاز التلفزيون."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"لم يتم تثبيت التطبيق لأنه ليس متوافقًا مع هاتفك."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"لم يتم تثبيت التطبيق لأن الحزمة تبدو غير صالحة."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> على جهازك اللوحي."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> على جهاز التلفزيون."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> على هاتفك."</string>
+ <string name="launch" msgid="4826921505917605463">"فتح"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"لا يسمح المشرف بتثبيت التطبيقات التي يتم الحصول عليها من مصادر غير معروفة"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"يتعذر على هذا المستخدم تثبيت التطبيقات غير المعروفة"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"غير مسموح لهذا المستخدم بتثبيت التطبيقات"</string>
+ <string name="ok" msgid="3468756155452870475">"موافق"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"إدارة التطبيقات"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"نفدت مساحة التخزين"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> يُرجى تحرير بعض المساحة والمحاولة مرة أخرى."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"لم يتم العثور على التطبيق"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"لم يتم العثور على التطبيق في قائمة التطبيقات المثبتة."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"غير مسموح به"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"غير مسموح للمستخدم الحالي بتنفيذ عملية إلغاء التثبيت هذه."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"الخطأ"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"تعذر إلغاء تثبيت التطبيق."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"إلغاء تثبيت التطبيق"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"إزالة التحديث"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> هو جزء من التطبيق التالي:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"هل تريد إزالة هذا التطبيق؟"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"هل تريد إزالة هذا التطبيق "<b>"لكل"</b>" المستخدمين؟ ستتم إزالة التطبيق وبياناته من "<b>"كل"</b>" المستخدمين على هذا الجهاز."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"هل تريد إزالة هذا التطبيق للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g>؟"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"عمليات إلغاء التثبيت الجارية"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"عمليات إلغاء التثبيت غير الناجحة"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"جارٍ الإزالة..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"جارٍ إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"انتهت الإزالة."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"تم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"تعذّر إلغاء التثبيت."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"لم يتم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> بنجاح."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"تعذر إلغاء تثبيت تطبيق مشرف الأجهزة النشطة"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"تعذر إلغاء تثبيت تطبيق مشرف الأجهزة النشطة لدى <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"هذا التطبيق مطلوب لبعض المستخدمين أو الملفات الشخصية وتم إلغاء تثبيته لآخرين."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"هذا التطبيق مطلوب لملفك الشخصي ولا يمكن إلغاء تثبيته."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"مشرف الجهاز يحتاج إلى هذا التطبيق ولا يمكن إزالته."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"إدارة تطبيقات مشرف الجهاز"</string>
+ <string name="manage_users" msgid="3125018886835668847">"إدارة حسابات المستخدمين"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"تعذرت إزالة <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"حدثت مشكلة أثناء تحليل الحزمة."</string>
+ <string name="newPerms" msgid="6039428254474104210">"جديد"</string>
+ <string name="allPerms" msgid="1024385515840703981">"الكل"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"الخصوصية"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"الدخول إلى الجهاز"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"لا يتطلب هذا التحديث أي أذونات جديدة."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"رفض"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"مزيد من المعلومات"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"الرفض على أي حال"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> من <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"هل توافق على منح <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> إذن <xliff:g id="ACTION">%2$s</xliff:g>؟"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"هل تريد السماح دائمًا للتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بهذا الإجراء: <xliff:g id="ACTION">%2$s</xliff:g>؟"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"أثناء استخدام التطبيق فقط"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"دائمًا"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"رفض وعدم طرح السؤال مرة أخرى"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> إذن غير مفعّل"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"كل الأذونات غير مفعّلة"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ليس هناك أذونات غير مفعّلة"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"سماح"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"التطبيقات"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"أذونات التطبيق"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"عدم السؤال مرة أخرى"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ما مِن أذونات"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"أذونات إضافية"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"فتح معلومات التطبيق"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g>لا أذونات أخرى</item>
+ <item quantity="two">إذنان آخران (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> أذونات أخرى</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> إذنًا آخر</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> من الأذونات الأخرى</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>إذن واحد آخر</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"تم تصميم هذا التطبيق لإصدار قديم من Android. وقد يؤدي رفض الإذن إلى عدم العمل على النحو المطلوب مرة أخرى."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"تنفيذ إجراء غير معروف"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"تم السماح لـ <xliff:g id="COUNT_0">%1$d</xliff:g> من أصل <xliff:g id="COUNT_1">%2$d</xliff:g> تطبيق"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"عرض النظام"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"إخفاء النظام"</string>
+ <string name="no_apps" msgid="1965493419005012569">"ليس هناك أي تطبيقات"</string>
+ <string name="location_settings" msgid="1774875730854491297">"إعدادات الموقع"</string>
+ <string name="location_warning" msgid="8778701356292735971">"يعد <xliff:g id="APP_NAME">%1$s</xliff:g> أحد مقدمي خدمات الموقع لهذا الجهاز. يمكن تعديل إمكانية الوصول إلى الموقع من إعدادات الموقع."</string>
+ <string name="system_warning" msgid="7103819124542305179">"في حال رفض هذا الإذن، قد لا تعمل ميزات أساسية في جهازك على النحو المنشود."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"فرضته إحدى السياسات"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"تمّ إيقاف الوصول إلى الخلفية بواسطة السياسة."</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"تمّ تفعيل الوصول إلى الخلفية بواسطة السياسة."</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"تمّ تفعيل الوصول إلى المقدمة بواسطة السياسة."</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"إعدادات يتحكم فيها المشرف"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"دائمًا"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"أثناء استخدام التطبيق فقط"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"أبدًا"</string>
+ <string name="loading" msgid="7811651799620593731">"جارٍ التحميل..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"كل الأذونات"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"إمكانات التطبيق الأخرى"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"طلب الإذن"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"تم اكتشاف طبقة متراكبة للشاشة"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"لتغيير إعداد هذا الإذن، يتعين عليك أولاً إيقاف الطبقة المتراكبة للشاشة من الإعدادات > التطبيقات"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"فتح الإعدادات"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"لا تتوافق إجراءات التثبيت/إلغاء التثبيت مع نظام Android Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"اختيار ما تريد السماح لتطبيق <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بالوصول إليه"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"تم تحديث <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. عليك اختيار ما تريد السماح لهذا التطبيق بالوصول إليه."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"إلغاء"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"متابعة"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"الأذونات الجديدة"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"الأذونات الحالية"</string>
+ <string name="message_staging" msgid="6151794817691100003">"جارٍ الطرح المرحلي للتطبيق…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"غير معروف"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"لأغراض الأمان، غير مسموح لجهازك اللوحي بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"لأغراض الأمان، غير مسموح لجهاز التلفزيون الذي تستخدمه بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"لأغراض الأمان، غير مسموح لهاتفك بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"يعتبر الهاتف والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لهاتفك أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"يعتبر الجهاز اللوحي والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث للجهاز اللوحي أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"يعتبر جهاز التلفزيون والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لجهاز التلفزيون أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"متابعة"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"الإعدادات"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"تثبيت / إلغاء تثبيت تطبيقات Android Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-as-television/strings.xml b/packages/PackageInstaller/res/values-as-television/strings.xml
new file mode 100644
index 0000000..2aaae1e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-as-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"অস্বীকাৰ কৰক আৰু পুনৰাই নুসুধিব"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"আপুনি ইয়াক পিছত ছেটিংসমূহ > এপসমূহ-লৈ গৈ সলনি কৰিব পাৰিব"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"ছিষ্টেম এপসমূহ দেখুৱাওক"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"এপৰ অনুমতিসমূহ"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"এপৰ অনুমতিসমূহ"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> অনুমতিসমূহ"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"অতিৰিক্ত অনুমতিসমূহ"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> অনুমতিসমূহ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-as-watch/strings.xml b/packages/PackageInstaller/res/values-as-watch/strings.xml
new file mode 100644
index 0000000..3889fc4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-as-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"অস্বীকাৰ কৰক আৰু পুনৰাই নুসুধিব"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"ছিষ্টেম এপসমূহ দেখুৱাওক"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"সলনি কৰিব নোৱাৰি"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"হয়"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"বাতিল কৰক"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml
new file mode 100644
index 0000000..de2f2d6
--- /dev/null
+++ b/packages/PackageInstaller/res/values-as/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"পেকেজ ইনষ্টলাৰ"</string>
+ <string name="next" msgid="3057143178373252333">"পৰৱৰ্তী"</string>
+ <string name="install" msgid="5896438203900042068">"ইনষ্টল কৰক"</string>
+ <string name="done" msgid="3889387558374211719">"সম্পন্ন হ\'ল"</string>
+ <string name="cancel" msgid="8360346460165114585">"বাতিল কৰক"</string>
+ <string name="installing" msgid="8613631001631998372">"ইনষ্টল কৰি থকা হৈছে…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ইনষ্টল কৰি থকা হৈছে…"</string>
+ <string name="install_done" msgid="3682715442154357097">"এপ্ ইনষ্টল কৰা হ\'ল।"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"আপুনি এই এপ্লিকেশ্বন ইনষ্টল কৰিব বিচাৰেনে? ই এইবোৰ ব্যৱহাৰ কৰিব পাৰিব:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"আপুনি এই এপ্লিকেশ্বন ইনষ্টল কৰিব বিচাৰেনে? ইয়াক ব্য়ৱহাৰ সম্পৰ্কীয় কোনো অনুমতিৰ প্ৰয়োজন নাই।"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"আপুনি পূর্বৰে পৰা থকা এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি কোনো পুৰণি ডেটা নেহেৰুৱাই। আপডেট হোৱা এপ্লিকেশ্বনে এইবোৰ ব্যৱহাৰ কৰিব পাৰিব:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"আপুনি এই অন্তনির্মিত এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি কোনো পুৰণি ডেটা নেহেৰুৱাই। আপডেট হোৱা এপ্লিকেশ্বনে এইবোৰ ব্যৱহাৰ কৰিব পাৰিব:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"আপুনি পূর্বৰে পৰা থকা এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি কোনো পুৰণি ডেটা নেহেৰুৱাব। ব্যৱহাৰৰ বাবে ইয়াক কোনো বিশেষ অনুমতিৰ প্ৰয়োজন নাই৷"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"আপুনি এই অন্তনির্মিত এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি নিজৰ পুৰণি ডেটা নেহেৰুৱাব৷ ব্যৱহাৰৰ বাবে ইয়াক কোনো বিশেষ অনুমতিৰ প্ৰয়োজন নাই৷"</string>
+ <string name="install_failed" msgid="6579998651498970899">"এপ্ ইনষ্টল কৰা হোৱা নাই।"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"পেকেজটোৰ ইনষ্টল অৱৰোধ কৰা হৈছে।"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"এপটো ইনষ্টল কৰিব পৰা নহ\'ল কাৰণ ইয়াৰ পেকেজ আৰু পূর্বৰে পৰা উপলব্ধ পেকেজৰ মাজত সমস্যাৰ সৃষ্টি হৈছে।"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"আপোনাৰ টেবলেটৰ সৈতে মিল নথকাৰ বাবে এপটো ইনষ্টল নহ\'ল।"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"আপোনাৰ টিভিত এই এপ্ চলিব নোৱাৰে।"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"আপোনাৰ ফ\'নৰ সৈতে মিল নথকাৰ বাবে এপটো ইনষ্টল নহ\'ল।"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"পেকেজ মান্য নোহোৱাৰ বাবে এপটো ইনষ্টল নহ\'ল।"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক আপোনাৰ টে\'বলেটত ইনষ্টল কৰিব পৰা নগ\'ল৷"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"আপোনাৰ টিভিত <xliff:g id="APP_NAME">%1$s</xliff:g> ইনষ্টল কৰিব পৰা নগ\'ল।"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক আপোনাৰ ফ\'নত ইনষ্টল কৰিব পৰা নগ\'ল৷"</string>
+ <string name="launch" msgid="4826921505917605463">"খোলক"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"আপোনাৰ প্ৰশাসকে অজ্ঞাত উৎসৰ পৰা লাভ কৰা এপ্ ইনষ্টল কৰাৰ অনুমতি দিয়া নাই"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"এই ব্যৱহাৰকাৰীয়ে অজ্ঞাত উৎসৰপৰা লাভ কৰা এপসমূহ ইনষ্টল কৰিব নোৱাৰে"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"এই ব্যৱহাৰকাৰীক এপ্ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই"</string>
+ <string name="ok" msgid="3468756155452870475">"ঠিক আছে"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"এপসমূহ পৰিচালনা কৰক"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"পৰ্যাপ্ত খালী ঠাই নাই"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক ইনষ্টল কৰিব পৰা নগ\'ল। কিছু খালী ঠাই উলিয়াই পুনৰ চেষ্টা কৰক৷"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"এপ্ পোৱা নগ\'ল"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ইনষ্টল হৈ থকা এপসমূহৰ তালিকাত এই এপটো পোৱা নগ\'ল।"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"অনুমতি দিয়া হোৱা নাই"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"বর্তমানৰ ব্যৱহাৰকাৰীক আনইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"আসোঁৱাহ"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"এপ্ আনইনষ্টল কৰিব পৰা নাযাব।"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"এপ্ আনইনষ্টল কৰক"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"আপডেট আনইনষ্টল কৰক"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> হৈছে তলৰ এপটোৰ এটা অংশ:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"আপুনি এই এপটো আনইনষ্টল কৰিব বিচাৰেনে?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"আপুনি "<b>"সকলো"</b>" ব্যৱহাৰকাৰীৰ বাবে এই এপটো আনইনষ্টল কৰিবলৈ বিচাৰেনে? এপ্লিকেশ্বন আৰু ইয়াৰ ডেটাক ডিভাইচটোত থকা "<b>"সকলো"</b>" ব্যৱহাৰকাৰীৰ পৰা আঁতৰোৱা হ\'ব৷"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"আপুনি ব্যৱহাৰকাৰী <xliff:g id="USERNAME">%1$s</xliff:g>ৰ বাবে এই এপটো আনইনষ্টল কৰিব বিচাৰেনে?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"এই এপটো ফেক্টৰী সংস্কৰণৰ সৈতে সলনি কৰিব বিচাৰেনে? সকলো তথ্য় মচা হ\'ব।"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"এই এপটো ফেক্টৰী সংস্কৰণৰ সৈতে সলনি কৰিব বিচাৰেনে? সকলো তথ্য় মচা হ\'ব। ইয়াৰ প্ৰভাৱ কার্মস্থানৰ প্ৰফাইল থকা ডিভাইচটোৰ ব্য়ৱহাৰকাৰীসকলৰ লগতে অইন সকলো ব্য়ৱহাৰকাৰীৰ ওপৰতো পৰিব।"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"আনইনষ্টল হৈ থকা বস্তুবোৰ"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"আনইনষ্টল কৰিব নোৱাৰা বস্তুবোৰ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"আনইনষ্টল কৰি থকা হৈছে…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ক আনইনষ্টল কৰি থকা হৈছে…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"আনইনষ্টল কাৰ্যটো সমাপ্ত হ\'ল৷"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰা হ\'ল"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"আনইনষ্টল কৰিব পৰা নগ\'ল।"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ক আনইনষ্টল কৰিব পৰা নগ\'ল।"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ডিভাইচৰ সক্ৰিয় প্ৰশাসক এপ্ আনইনষ্টল কৰিব নোৱাৰি"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>ৰ সক্ৰিয় ডিভাইচৰ প্ৰশাসকীয় এপ্ আনইনষ্টল কৰিব নোৱাৰি"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"এই এপটো কিছুসংখ্য়ক ব্যৱহাৰকাৰী বা প্ৰ\'ফাইলৰ বাবে প্ৰয়োজনীয় আৰু বাকীসকলৰ বাবে ইয়াক আনইনষ্টল কৰা হৈছে"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"আপোনাৰ প্ৰ\'ফাইলৰ বাবে এই এপৰ প্ৰয়োজন আছে গতিকে আনইনষ্টল কৰিব পৰা নাযায়।"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"আপোনাৰ ডিভাইচৰ প্ৰশাসকে এই এপটো ৰখাটো বাধ্যতামূলক কৰি ৰাখিছে, গতিকে ইয়াক আনইনষ্টল কৰিব পৰা নাযায়।"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ডিভাইচৰ প্ৰশাসকীয় এপসমূহ পৰিচালনা কৰক"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ব্য়ৱহাৰকাৰীসকলক পৰিচালনা কৰক"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক আনইনষ্টল কৰিব নোৱাৰি৷"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"পেকেজটো পাৰ্ছ কৰোঁতে এটা সমস্যাই দেখা দিছিল।"</string>
+ <string name="newPerms" msgid="6039428254474104210">"নতুন"</string>
+ <string name="allPerms" msgid="1024385515840703981">"সকলো"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"গোপনীয়তা"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ডিভাইচৰ ব্যৱহাৰ"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"এই আপডেটক কোনো নতুন অনুমতিৰ প্ৰয়োজন নাই।"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"প্ৰত্যাখ্যান কৰক"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"অধিক তথ্য"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"যিহ\'লেও অস্বীকাৰ কৰক"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>ৰ ভিতৰত<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>টা"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ক <xliff:g id="ACTION">%2$s</xliff:g>ৰ বাবে অনুমতি দিবনে?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ক সদায় <xliff:g id="ACTION">%2$s</xliff:g> কৰাৰ অনুমতি দিবনে?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"এপ্ ব্য়ৱহাৰ কৰি থাকোঁতে মাত্ৰ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"সদায়"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"অস্বীকাৰ কৰক আৰু পুনৰাই নুসুধিব"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>টা অক্ষম কৰা হ\'ল"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"সকলো অক্ষম কৰা হ\'ল"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"একো অক্ষম কৰা হোৱা নাই"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"অনুমতি দিয়ক"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"এপসমূহ"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"এপক দিয়া অনুমতিসমূহ"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"পুনৰাই নুসুধিব"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"কোনো অনুমতি নাই"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"অতিৰিক্ত অনুমতিসমূহ"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"এপৰ তথ্য় খোলক"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> অধিক</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> অধিক</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"এই এপটো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে প্ৰস্তুত কৰা হৈছিল। অনুমতি নিদিলে ই বিচৰাধৰণে কাম নকৰিবও পাৰে।"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"অজ্ঞাত কাৰ্য কৰিব পাৰে"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>ৰ ভিতৰত<xliff:g id="COUNT_0">%1$d</xliff:g>টা এপক অনুমতি দিয়া হৈছে"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"ছিষ্টেম দেখুৱাওক"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"ছিষ্টেম লুকুৱাওক"</string>
+ <string name="no_apps" msgid="1965493419005012569">"কোনো এপে এই অনুমতি বিচৰা নাই"</string>
+ <string name="location_settings" msgid="1774875730854491297">"অৱস্থান ছেটিংসমূহ"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই ডিভাইচৰ অৱস্থান সেৱা প্ৰদানকাৰী। অৱস্থানৰ ছেটিংসমূহত অৱস্থানৰ ব্যৱহাৰ সংশোধন কৰিব পাৰি।"</string>
+ <string name="system_warning" msgid="7103819124542305179">"আপুনি যদি এই অনুমতি প্ৰদান নকৰে, তেন্তে আপোনাৰ ডিভাইচৰ মৌলিক সুবিধাসমূহে বিচৰাধৰণে কাম নকৰিবও পাৰে।"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"নীতিৰ যোগেদি বলৱৎ কৰা"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"নীতি অনুসৰি নেপথ্য় চোৱা সুবিধা অক্ষম কৰা হ’ল"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"নীতি অনুসৰি নেপথ্য় চোৱা সুবিধা সক্ষম কৰা হ’ল"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"নীতি অনুসৰি অগ্ৰভূমি চোৱা সুবিধা সক্ষম কৰা হ’ল"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"প্ৰশাসকে নিয়ন্ত্ৰিত কৰা"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"সদায়"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"এপ্ ব্য়ৱহাৰ কৰি থাকোঁতে মাত্ৰ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"কেতিয়াও নহয়"</string>
+ <string name="loading" msgid="7811651799620593731">"ল\'ড কৰি থকা হৈছে…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"সকলো অনুমতি"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"অন্য এপৰ কার্যক্ষমতাসমূহ"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"অনুমতি বিচাৰি কৰা অনুৰোধ"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"স্ক্ৰীণ অভাৰলে\' চিনাক্ত কৰা হৈছে"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"এই অনুমতিৰ ছেটিং সলনি কৰিবলৈ আপুনি প্ৰথমে ছেটিংসমূহ > এপসমূহ-লৈ গৈ স্ক্ৰীণ অভাৰলে\' অফ কৰিব লাগিব।"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ছেটিংসমূহ খোলক"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android ৱেৰ"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ইনষ্টল/আনইনষ্টল কাৰ্য Wearত কৰিব নোৱাৰি।"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ক কি কিত প্ৰৱেশ কৰিবলৈ অনুমতি দিব বাছনি কৰক"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> আপডেট কৰা হৈছে। এই এপক কি কিত প্ৰৱেশ কৰিবলৈ অনুমতি দিব বাছনি কৰক।"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"বাতিল কৰক"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"অব্যাহত ৰাখক"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"নতুন অনুমতিসমূহ"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"এপে বর্তমান ব্যৱহাৰ কৰি থকা অনুমতিসমূহ"</string>
+ <string name="message_staging" msgid="6151794817691100003">"এপৰ অন্তিম পর্যায়ৰ পৰীক্ষণ চলি আছে…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"অজ্ঞাত"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"আপোনাৰ টেবলেটটো যাতে সুৰক্ষিত থাকে তাৰ বাবে আপোনাৰ টেবলেটটোক এই উৎসৰ পৰা অজ্ঞাত এপসমূহ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"আপোনাৰ টিভিটো যাতে সুৰক্ষিত থাকে তাৰ বাবে আপোনাৰ টিভিটোক এই উৎসৰ পৰা অজ্ঞাত এপসমূহ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"আপোনাৰ ফ\'নটো যাতে সুৰক্ষিত থাকে তাৰ বাবে আপোনাৰ ফ\'নটোক এই উৎসৰ পৰা অজ্ঞাত এপসমূহ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"আপোনাৰ টিভি আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। এই এপটো ইনষ্টল কৰি আপুনি ইয়াক ব্যৱহাৰ কৰাৰ ফলত আপোনাৰ ফ\'নত কোনো ক্ষতি হ\'লে বা ডেটা হেৰুৱালে আপুনিয়েই দায়ী হ\'ব বুলি সন্মত।"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"আপোনাৰ টেবলেট আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। এই এপটো ইনষ্টল কৰি আপুনি ইয়াক ব্যৱহাৰ কৰাৰ ফলত আপোনাৰ টেবলেটত কোনো ক্ষতি হ\'লে বা ডেটা হেৰুৱালে আপুনিয়েই দায়ী হ\'ব বুলি সন্মত।"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"আপোনাৰ টিভি আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। এই এপটো ইনষ্টল কৰি আপুনি ইয়াক ব্যৱহাৰ কৰাৰ ফলত আপোনাৰ টিভিত কোনো ক্ষতি হ\'লে বা ডেটা হেৰুৱালে আপুনিয়েই দায়ী হ\'ব বুলি সন্মত।"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"অব্যাহত ৰাখক"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ছেটিংবোৰ"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"ৱেৰ এপসমূহ ইনষ্টল/আনইনষ্টল কৰি থকা হৈছে"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-az-television/strings.xml b/packages/PackageInstaller/res/values-az-television/strings.xml
new file mode 100644
index 0000000..92fa527
--- /dev/null
+++ b/packages/PackageInstaller/res/values-az-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Rədd edin və daha soruşmayın"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Bunu sonra Ayarlar vəTətbiqlər bölməsindən dəyişə bilərsiniz"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Sistem tətbiqlərini göstərin"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Tətbiq icazələri"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Tətbiq icazələri"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> icazələri"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Əlavə icazələr"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> icazələri"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-az-watch/strings.xml b/packages/PackageInstaller/res/values-az-watch/strings.xml
new file mode 100644
index 0000000..ef6723b
--- /dev/null
+++ b/packages/PackageInstaller/res/values-az-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Rədd edin, bir daha soruşmayın"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Sistem tətbiqlərini göstərin"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Dəyişdirilə bilməz"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Bəli"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Ləğv edin"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml
new file mode 100644
index 0000000..d870887
--- /dev/null
+++ b/packages/PackageInstaller/res/values-az/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Paket quraşdırıcı"</string>
+ <string name="next" msgid="3057143178373252333">"Növbəti"</string>
+ <string name="install" msgid="5896438203900042068">"Quraşdır"</string>
+ <string name="done" msgid="3889387558374211719">"Hazırdır"</string>
+ <string name="cancel" msgid="8360346460165114585">"Ləğv et"</string>
+ <string name="installing" msgid="8613631001631998372">"Quraşdırılır..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> quraşdırılır…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Tətbiq quraşdırılıb."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Bu tətbiqi quraşdırmaq istəyirsiniz? Tətbiq buraya giriş əldə edəcək:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bu tətbiqi quraşdırmaq istəyirsiniz? Hər hansı bir xüsusi keçid tələb etmir."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Bu cari tətbiq güncəllənməsini quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. Güncəllənmiş tətbiq aşağıdakılara çıxış əldə edəcək:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Daxili tətbiqdən yenilənməni quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. Yenilənmiş tətbiq aşağıdakılara çıxış əldə edəcək:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Bu cari tətbiq güncəllənməsini quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. O, xüsusi giriş tələb etmir."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Bu daxili tətbiq güncəllənməsini quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. O, xüsusi giriş tələb etmir."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Tətbiq quraşdırılmayıb."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paket yüklənməyə qarşı blok edildi."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Bu paketin mövcud paket ilə ziddiyəti səbəbiylə tətbiq quraşdırılmadı."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Bu tətbiq planşetinizə uyğun gəlmədiyi üçün tətbiq quraşdırılmadı."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Bu proqram TV-nizlə uyğun gəlmir."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Bu tətbiq telefonunuza uyğun gəlmədiyi üçün tətbiq quraşdırılmadı."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Paket yanlış kimi göründüyü üçün tətbiq quraşdırılmadı."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> planşetinizə yüklənə bilmədi."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> proqramını TV-nizdə quraşdırmaq mümkün olmadı."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> telefonunuza quraşdırıla bilmədi."</string>
+ <string name="launch" msgid="4826921505917605463">"Aç"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Naməlum mənbələrdən əldə edilmiş tətbiqlərin quraşdırılmasına admin tərəfindən icazə verilmir"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Naməlum tətbiqlər bu istifadəçi tərəfindən quraşdırıla bilməz"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Bu istifadəçinin tətbiqi quraşdırmaq üçün icazəsi yoxdur"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Tətbiqləri idarə et"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Boş yer yoxdur"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> quraşdırıla bilməz. Yaddaş üçün yer boşaldıb yenidən təkrar edin."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Tətbiq tapılmadı"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Tətbiq quraşdırılmış tətbiqlər siyahısında tapılmadı."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"İcazə verilmir"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Cari istifadəçiyə bu silinməni həyata keçirməyə icazə verilmir."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Xəta"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Tətbiq sistemdən silinmədi."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Tətbiqi qaldır"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Güncəlləməni sil"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> bu tətbiqin hissəsidir:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Bu tətbiqi aradan qaldırmaq istəyirsiniz mi?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Bu tətbiqi "<b>"bütün"</b>" istifadəçilər üçün silmək istəyirsiz? Tətbiq və onun datası cihazdakı "<b>"bütün"</b>" istifadəçilər üçün silinəcək."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı istifadəçi üçün bu tətbiqi sistemdən silmək istəyirsiniz?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək. Bu, iş profilləri olanlar da daxil olmaqla bu cihazın bütün istifadəçilərinə təsir edir."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"İşləyən sistemlər silinmələr"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Uğursuz olan sistemlər silinmələr"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Silinir..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinir…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Sistemdən silmə tamamlandı."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silindi"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Aradan qaldırılma uğursuz oldu."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinməsi uğursuz oldu."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktiv cihaz admin tətbiqini sistemdən silmək mümkün olmadı"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün aktiv cihaz admin tətbiqini sistemdən silmək mümkün olmadı"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Bu tətbiq bəzi istifadəçi və profillər tərəfindən tələb olunur və digərləri üçün silinib"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Bu tətbiq profil üçün tələb olunur və silinə bilməz."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Bu tətbiq cihaz administratoru tərəfindən tələb olunur və sistemdən silinə bilməz."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Cihaz admin tətbiqlərini idarə edin"</string>
+ <string name="manage_users" msgid="3125018886835668847">"İstifadəçiləri idarə edin"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> sistemdən silinə bilməz."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketin təhlilində problem var idi."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Yeni"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Hamısı"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Məxfilik"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Qurğu icazəsi"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Bu güncəllənmə heç bir icazə istəmir"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Rədd edin"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Daha ətraflı"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Hər bir halda rədd edin"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> icazədən <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ədəd"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqinə <xliff:g id="ACTION">%2$s</xliff:g> fəaliyyəti üçün icazə verilsin?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqinin <xliff:g id="ACTION">%2$s</xliff:g> əməliyyatına daima icazə verilsin?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Ancaq tətbiq istifadəsi zamanı"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Həmişə"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Rədd edin və daha soruşmayın"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> deaktiv edildi"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"hamısı deaktiv edildi"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"heç biri deaktiv edilmədi"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"İcazə verin"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Tətbiqlər"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Tətbiq icazələri"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Bir daha soruşmayın"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"İcazə yoxdur"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Əlavə icazələr"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Tətbiq məlumatını açın"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">daha <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">daha <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Bu tətbiq köhnə Android versiyası üçün nəzərdə tutulub. İcazəni rədd etmək onun lazımi şəkildə işləməməsinə səbəb ola bilər."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"naməlum əməliyyat etmək"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> tətbiqdən <xliff:g id="COUNT_0">%1$d</xliff:g> ədədinə icazə var"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Sistemi göstərin"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Sistemi gizlədin"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Tətbiq yoxdur"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Məkan Ayarları"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu cihaz üçün məkan xidmətləri təminatçısıdır. Məkana giriş məkan ayarlarından dəyişdirilə bilər."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Bu icazəni rədd etsəniz, cihazınızın əsas funksiyaları lazımi qaydada işləməyə bilər."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Siyasət tərəfindən tətbiq olunur"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Arxa fon girişi siyasətə əsasən deaktiv edildi"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Arxa fon girişi siyasətə əsasən aktiv edildi"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ön fon girişi siyasətə əsasən aktiv edildi"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Admin tərəfindən nəzarət olunur"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Həmişə"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Ancaq tətbiq istifadəsi zamanı"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Heç vaxt"</string>
+ <string name="loading" msgid="7811651799620593731">"Yüklənir…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Bütün icazələr"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Digər tətbiq imkanları"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"İcazə sorğusu"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Ekran örtüyü aşkarlandı"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Bu icazə ayarını dəyişdirmək üçün əvvəldə Ayarlar və Tətbiqlər bölməsindən ekran örtüyünü söndürməlisiniz"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Ayarları açın"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Yükləmə/Silmə fəaliyyətləri Wear\'də dəstəklənmir."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqinin giriş hüququnu seçin"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tətbiqi güncəlləndi. Bu tətbiqin giriş hüququnu seçin."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Ləğv edin"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Davam edin"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Yeni icazələr"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Cari icazələr"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Tətbiq hazırlanır..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Naməlum"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Təhlükəsizliyiniz üçün planşetə bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Təhlükəsizliyiniz üçün TV-yə bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Təhlükəsizliyiniz üçün telefona bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla telefona dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verən data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Planşet və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla planşetə dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verə biləcək data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tv və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla Tv\'ə dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verən data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Davam edin"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Ayarlar"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear tətbiqləri quraşdırılır/silinir"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn-television/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn-television/strings.xml
new file mode 100644
index 0000000..5dce759
--- /dev/null
+++ b/packages/PackageInstaller/res/values-b+sr+Latn-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Odbij i ne pitaj ponovo"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Ovo možete da promenite kasnije u Podešavanjima > Aplikacije"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Prikaži sistemske aplikacije"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Dozvole za aplikacije"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Dozvole za aplikacije"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Dozvole za aplikaciju <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Dodatne dozvole"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Dozvole za aplikaciju <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn-watch/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn-watch/strings.xml
new file mode 100644
index 0000000..63a44db
--- /dev/null
+++ b/packages/PackageInstaller/res/values-b+sr+Latn-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Odbij i ne pitaj ponovo"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Prikaži sistemske aplikacije"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Ne može da se promeni"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Da"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Otkaži"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..4d8772f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Upakovani program za instalaciju"</string>
+ <string name="next" msgid="3057143178373252333">"Dalje"</string>
+ <string name="install" msgid="5896438203900042068">"Instaliraj"</string>
+ <string name="done" msgid="3889387558374211719">"Gotovo"</string>
+ <string name="cancel" msgid="8360346460165114585">"Otkaži"</string>
+ <string name="installing" msgid="8613631001631998372">"Instaliranje..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instalira se <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikacija je instalirana."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Želite li da instalirate ovu aplikaciju? Imaće pristup sledećem:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Želite li da instalirate ovu aplikaciju? Ne zahteva poseban pristup."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Želite li da instalirate ažuriranje za ovu postojeću aplikaciju? Postojeći podaci neće biti izgubljeni. Ažurirana aplikacija imaće pristup sledećem:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Želite li da instalirate ažuriranje za ovu ugrađenu aplikaciju? Postojeći podaci neće biti izgubljeni. Ažurirana aplikacija će imati pristup sledećem:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Da li želite da instalirate ažuriranje ove postojeće aplikacije? Postojeći podaci neće biti izgubljeni. Nije potreban poseban pristup."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Da li želite da instalirate ažuriranje ove ugrađene aplikacije? Postojeći podaci neće biti izgubljeni. Nije potreban poseban pristup."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikacija nije instalirana."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Instaliranje paketa je blokirano."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija nije instalirana jer je paket neusaglašen sa postojećim paketom."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija nije instalirana jer nije kompatibilna sa tabletom."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ova aplikacija nije kompatibilna sa TV-om."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija nije instalirana jer nije kompatibilna sa telefonom."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija nije instalirana jer je paket nevažeći."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nismo uspeli da instaliramo <xliff:g id="APP_NAME">%1$s</xliff:g> na TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na telefon."</string>
+ <string name="launch" msgid="4826921505917605463">"Otvori"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administrator ne dozvoljava instaliranje aplikacija dobijenih iz nepoznatih izvora"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ovaj korisnik ne može da instalira nepoznate aplikacije"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ovom korisniku nije dozvoljeno da instalira aplikacije"</string>
+ <string name="ok" msgid="3468756155452870475">"Potvrdi"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Upravljanje aplikacijama"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nema više mesta"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite dodatni prostor i pokušajte ponovo."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacija nije pronađena"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacija nije pronađena na listi instaliranih aplikacija."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nije dozvoljeno"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Aktuelnom korisniku nije dozvoljeno da obavi ovo deinstaliranje."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Greška"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Deinstaliranje aplikacije nije uspelo."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Deinstaliranje aplikacije"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Deinstaliranje ažuriranja"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je deo sledeće aplikacije:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Da li želite da deinstalirate ovu aplikaciju?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Da li želite da deinstalirate ovu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i podaci koji se na nju odnose biće uklonjeni za "<b>"sve"</b>" korisnike ovog uređaja."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Želite li da deinstalirate ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni. Ovo utiče na sve korisnike ovog uređaja, uključujući i one sa profilima za Work."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Aktivna deinstaliranja"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspela deinstaliranja"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Deinstaliranje..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se deinstalira…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Deinstaliranje je završeno."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je deinstalirana"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Deinstaliranje nije uspelo."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspelo."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ova aplikacija je potrebna za neke korisnike ili profile, a deinstalirana je za druge"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ova aplikacija je potrebna za vaš profil i ne može da se deinstalira."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ova aplikacija je potrebna administratoru uređaja i ne može da se deinstalira."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Upravljaj aplikacijama za administratore uređaja"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Upravljaj korisnicima"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nije moguće deinstalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Došlo je do problema pri raščlanjivanju paketa."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Sve"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privatnost"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Pristup uređaju"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Ovo ažuriranje ne zahteva nove dozvole."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odbaci"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Više informacija"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Ipak odbij"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Želite li da dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Želite li uvek da dozvolite da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo dok se aplikacija koristi"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Uvek"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odbij i ne pitaj ponovo"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Onemogućenih: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"sve su onemogućene"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nijedna nije onemogućena"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dozvoli"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Dozvole za aplikacije"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ne pitaj ponovo"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nema dozvola"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Dodatne dozvole"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvori informacije o aplikaciji"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ova aplikacija je dizajnirana za stariju verziju Android-a. Ako odbijete dozvolu, ona možda više neće pravilno da funkcioniše."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"obavlja nepoznatu radnju"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g> aplikacija ima dozvolu"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Prikaži sistemske"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Sakrij sistemske"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nema aplikacija"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Podešavanja lokacije"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> pruža usluge lokacije za ovaj uređaj. Pristup lokaciji možete da izmenite u podešavanjima lokacije."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ako odbijete ovu dozvolu, osnovne funkcije uređaja možda neće više funkcionisati ispravno."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Primenjuje se u skladu sa smernicama"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Pristup u pozadini je onemogućen smernicama"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Pristup u pozadini je omogućen smernicama"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Pristup u prvom planu je omogućen smernicama"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontroliše administrator"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Uvek"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo dok se aplikacija koristi"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nikada"</string>
+ <string name="loading" msgid="7811651799620593731">"Učitava se…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Sve dozvole"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Ostale mogućnosti aplikacije"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Zahtev za dozvolu"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Otkriven je element koji prekriva sadržaj ekrana"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Da biste promenili podešavanje ove dozvole, prvo treba da isključite element koji prekriva sadržaj ekrana u odeljku Podešavanja > Aplikacije"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Otvori podešavanja"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Radnje Instaliraj/Deinstaliraj nisu podržane u Wear-u."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Izaberite čemu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> može da pristupa"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> je ažurirana. Izaberite čemu ova aplikacija može da pristupa."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Otkaži"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Nastavi"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nove dozvole"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Aktuelne dozvole"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Aplikacija se priprema…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Nepoznato"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Tabletu iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Televizoru iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Telefonu iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja telefona ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tablet i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja tableta ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja TV-a ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Nastavi"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Podešavanja"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instaliranje/deinstaliranje Wear aplikacija"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-be-television/strings.xml b/packages/PackageInstaller/res/values-be-television/strings.xml
new file mode 100644
index 0000000..befb367
--- /dev/null
+++ b/packages/PackageInstaller/res/values-be-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Адхіліць і больш не пытацца"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Пазней гэта можна змянiць у раздзеле «Налады > Праграмы»"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Паказваць сістэмныя праграмы"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Дазволы праграм"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Дазволы праграм"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Дазволы праграмы <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Дадатковыя дазволы"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Дазволы праграмы <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-be-watch/strings.xml b/packages/PackageInstaller/res/values-be-watch/strings.xml
new file mode 100644
index 0000000..99b2ce8
--- /dev/null
+++ b/packages/PackageInstaller/res/values-be-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Адхіліць, больш не пытацца"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Паказваць сістэмныя праграмы"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Нельга змяніць"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Так"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Скасаваць"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
new file mode 100644
index 0000000..1b65e29
--- /dev/null
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Усталёўшчык пакетаў"</string>
+ <string name="next" msgid="3057143178373252333">"Далей"</string>
+ <string name="install" msgid="5896438203900042068">"Усталяваць"</string>
+ <string name="done" msgid="3889387558374211719">"Гатова"</string>
+ <string name="cancel" msgid="8360346460165114585">"Скасаваць"</string>
+ <string name="installing" msgid="8613631001631998372">"Усталяванне..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Ідзе ўсталяванне <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Прыкладанне ўсталявана."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Усталяваць гэта прыкладанне? Яно атрымае доступ да:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Усталяваць гэта прыкладанне? Яно не патрабуе спецыяльнага доступу."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Усталяваць абнаўленне для гэтага існуючага прыкладання? Існуючыя дадзеныя не будуць страчаны. Абноўленае прыкладанне атрымае доступ да:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Усталяваць абнаўленне для гэтага ўбудаванага прыкладання? Існуючыя дадзеныя не будуць страчаны. Абноўленае прыкладанне атрымае доступ да:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Усталяваць абнаўленне для гэтага прыкладання? Вашы iснуючыя дадзеныя не будуць згублены. Спецыяльны доступ не патрабуецца."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Усталяваць абнаўленне для гэтага ўбудаванага прыкладання? Вашы iснуючыя дадзеныя не будуць згублены. Спецыяльны доступ не патрабуецца."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Прыкладанне не ўсталявана."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Для пакета заблакіравана магчымасць усталявання."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Праграма не ўсталявана, таму што пакет канфліктуе з існуючым пакетам."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Праграма не ўсталявана, таму што яна несумяшчальная з вашым планшэтам."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Гэта праграма несумяшчальная з вашым тэлевізарам."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Праграма не ўсталявана, таму што яна несумяшчальная з вашым тэлефонам."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Праграма не ўсталявана, таму што пакет, магчыма, з\'яўляецца несапраўдным."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"На гэтым планшэце немагчыма ўсталяваць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"На вашым тэлевізары немагчыма ўсталяваць праграму <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"На гэтым тэлефоне немагчыма ўсталяваць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="launch" msgid="4826921505917605463">"Адкрыць"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ваш адміністратар не дазваляе ўсталёўку праграм з невядомых крыніц."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Гэты карыстальнік не можа ўсталёўваць невядомыя праграмы"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Гэты карыстальнік не можа ўсталёўваць праграмы"</string>
+ <string name="ok" msgid="3468756155452870475">"ОК"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Кіраванне прыкладаннямі"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Не хапае месца"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Немагчыма ўсталяваць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>. Вызваліце месца і паўтарыце спробу."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Прыкладанне не знойдзена"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Прыкладанне не знойдзена ў спісе ўсталяваных прыкладанняў."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Забаронена"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Бягучы карыстальнік не мае дазволу на гэта выдаленне."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Памылка"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Нельга выдаліць праграму."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Выдалiць прыкладанне"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Выдаліць абнаўленні"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> з\'яўляецца часткай наступнага прыкладання:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Выдаліць гэта прыкладанне?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Выдалiць гэта прыкладанне для "<b>"ўсiх"</b>" карыстальнirfў? Прыкладанне i яго дадзеныя будуць выдалены для "<b>"ўсiх"</b>" карыстальнiкаў прылады."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Хочаце выдаліць гэту праграму для карыстальніка <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Замяніць гэту праграму заводскай версіяй? Усе даныя будуць выдалены."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Замяніць гэту праграму заводскай версіяй? Усе даныя будуць выдаленыя. Гэта паўплывае на ўсіх карыстальнікаў гэтай прылады, у тым ліку карыстальнікаў з працоўнымі профілямі."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Актыўныя выдаленні"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Збоі выдалення"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Выдаленне..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> выдаляецца…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Выдаленне завершана"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Выдалена <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Няўдалае выдаленне."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Не атрымалася выдаліць <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Немагчыма выдаліць актыўную праграму адміністратара прылады"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Немагчыма выдаліць актыўную праграму адміністратара прылады для карыстальніка <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Гэта праграма патрабуецца для некаторых карыстальнікаў або профіляў і была выдалена для іншых"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Гэта праграма неабходная для вашага профілю і не можа быць выдалена."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Гэта праграма патрабуецца адміністратару вашай прылады і не можа быць выдалена."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Праграмы адміністратара для кіравання прыладамі"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Кіраванне карыстальнікамі"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Немагчыма выдалiць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Памылка аналiзу пакета."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Новыя"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Усе"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Прыватнасць"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Доступ да прылады"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Гэтае абнаўленне не патрабуе ніякіх новых дазволаў."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Адмовіць"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Дадатковая iнфармацыя"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Усё роўна адмовіць"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> з <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Дазволіць <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Заўсёды дазваляць праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Толькі пры актыўнай праграме"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Заўсёды"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Адхіліць і больш не пытацца"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Адключана: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"усе адключаны"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"няма адключаных"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Дазволіць"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Праграмы"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Дазволы праграм"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Больш не пытацца"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Няма дазволаў"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Дадатковыя дазволы"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Паказаць звесткі пра праграму"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> іншы</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> іншыя</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> іншых</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> іншага</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Гэта праграма была распрацавана для больш старой версіі Android. Адхіленне дазволу можа прывесці да таго, што яна не будзе працаваць належным чынам."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"выканаць невядомае дзеянне"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> з <xliff:g id="COUNT_1">%2$d</xliff:g> праграм з дазволам"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Паказаць сістэмныя"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Схаваць сістэмныя"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Няма праграм"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Налады месцазнаходжання"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> з\'яўляецца службай вызначэння месцазнаходжання для гэтай прылады. Доступ да вызначэння месцазнаходжання можна змяніць у наладах вызначэння месцазнаходжання."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Калі вы адхіліце гэты дазвол, асноўныя функцыі прылады могуць перастаць працаваць належным чынам."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Ажыццёўлена палітыкай"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Доступ у фонавым рэжыме адключаны згодна з правіламі"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Доступ у фонавым рэжыме ўключаны згодна з правіламі"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Доступ у актыўным рэжыме ўключаны згодна з правіламі"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Кантралюецца адміністратарам"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Заўсёды"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Толькі пры актыўнай праграме"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Ніколі"</string>
+ <string name="loading" msgid="7811651799620593731">"Загрузка..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Усе дазволы"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Іншыя магчымасці праграмы"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Запыт дазволу"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Выяўлены слой экрана"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Каб змяніць гэту наладу дазволу, вы павінны спачатку выключыць слой экрана з меню Налады > Праграмы"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Адкрыць налады"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Дзеянні па ўсталяванні або выдаленні не падтрымліваюцца на Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Выберыце, да чаго дазволіць доступ праграме <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Праграма <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> была абноўлена. Выберыце, да чаго ёй дазволіць доступ."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Скасаваць"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Далей"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Новыя дазволы"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Бягучыя дазволы"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Падрыхтоўка праграмы..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Невядома"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"У мэтах бяспекі вашаму планшэту не дазваляецца ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"У мэтах бяспекі вашаму тэлевізару не дазваляецца ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"У мэтах бяспекі вашаму тэлефону не дазваляецца ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ваш тэлефон і асабістыя даныя больш уразлівыя для нападаў невядомых праграм. Пры ўсталёўцы гэтай праграмы вы згаджаецеся, што несяце адказнасць за любыя пашкоджанні тэлефона ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ваш планшэт і асабістыя даныя больш уразлівыя для нападаў невядомых праграм. Пры ўсталёўцы гэтай праграмы вы згаджаецеся, што несяце адказнасць за любыя пашкоджанні планшэта ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ваш тэлевізар і асабістыя даныя больш уразлівыя для нападаў невядомых праграм. Пры ўсталёўцы гэтай праграмы вы згаджаецеся, што несяце адказнасць за любыя пашкоджанні тэлевізара ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Працягнуць"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Налады"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Усталяванне/выдаленне праграм wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bg-television/strings.xml b/packages/PackageInstaller/res/values-bg-television/strings.xml
new file mode 100644
index 0000000..7429955
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bg-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Отказване, без повторно запитване"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Можете да промените това по-късно от „Настройки“ > „Приложения“"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Показване на системните приложения"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Разрешения за приложението"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Разрешения за приложението"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Разрешения за <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Допълнителни разрешения"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Разрешения за <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bg-watch/strings.xml b/packages/PackageInstaller/res/values-bg-watch/strings.xml
new file mode 100644
index 0000000..b71606b
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bg-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Отказ, без повторно запитване"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Показване на системните приложения"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Без промяна"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Да"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Отказ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
new file mode 100644
index 0000000..30d99eb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Инсталираща програма за пакети"</string>
+ <string name="next" msgid="3057143178373252333">"Напред"</string>
+ <string name="install" msgid="5896438203900042068">"Инсталиране"</string>
+ <string name="done" msgid="3889387558374211719">"Готово"</string>
+ <string name="cancel" msgid="8360346460165114585">"Назад"</string>
+ <string name="installing" msgid="8613631001631998372">"Инсталира се..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се инсталира…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Приложението бе инсталирано."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Искате ли да инсталирате това приложение? То ще получи достъп до:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Искате ли да инсталирате това приложение? То не изисква никакъв специален достъп."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Искате ли да инсталирате актуализация за това съществуващо приложение? Съществуващите ви данни няма да бъдат загубени. Актуализираното приложение ще получи достъп до:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Искате ли да инсталирате актуализация за това вградено приложение? Съществуващите ви данни няма да бъдат загубени. Актуализираното приложение ще получи достъп до:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Искате ли да инсталирате актуализация за това съществуващо приложение? Съществуващите ви данни няма да бъдат загубени. Не се изисква специален достъп."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Искате ли да инсталирате актуализация за това вградено приложение? Съществуващите ви данни няма да бъдат загубени. Не се изисква специален достъп."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Приложението не бе инсталирано."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Инсталирането на пакета бе блокирано."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Приложението не бе инсталирано, тъй като пакетът е в конфликт със съществуващ пакет."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Приложението не бе инсталирано, тъй като не е съвместимо с таблета ви."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Това приложение не е съвместимо с телевизора ви."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Приложението не бе инсталирано, тъй като не е съвместимо с телефона ви."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Приложението не бе инсталирано, тъй като изглежда, че пакетът е невалиден."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира на таблета ви."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира на телевизора ви."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира на телефона ви."</string>
+ <string name="launch" msgid="4826921505917605463">"Отваряне"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Администраторът ви не разрешава инсталирането на приложения, получени от неизвестни източници"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Този потребител не може да инсталира неизвестни приложения"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Този потребител няма разрешение да инсталира приложения"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Управление на приложенията"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Няма място"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира. Освободете място и опитайте отново."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Приложението не бе намерено"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Приложението не бе намерено в списъка с инсталирани приложения."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Няма разрешение"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Текущият потребител няма разрешение да извърши това деинсталиране."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Грешка"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Приложението не можа да бъде деинсталирано."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Деинсталиране на приложението"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Деинсталиране на актуализацията"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> е част от следното приложение:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Искате ли да деинсталирате това приложение?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Искате ли да деинсталирате това приложение за "<b>"всички"</b>" потребители? Приложението и данните му ще бъдат премахнати от "<b>"всички"</b>" потребители на устройството."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Искате ли да деинсталирате това приложение за потребителя <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Това приложение да се замени ли с фабричната версия? Всички данни ще бъдат премахнати."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Това приложение да се замени ли с фабричната версия? Всички данни ще бъдат премахнати. Промяната ще засегне всеки потребител на устройството, включително тези със служебни потребителски профили."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активни деинсталирания"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Неуспешни деинсталирания"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Деинсталира се..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Деинсталирането завърши."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Деинсталирахте <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Деинсталирането не бе успешно."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Деинсталирането на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> бе неуспешно."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Активното приложение за администриране на устройството не може да се деинсталира"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Активното приложение за администриране на устройството не може да се деинсталира за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Това приложение е необходимо за някои потребители или потребителски профили и бе деинсталирано за други."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Това приложение е необходимо за потребителския ви профил и не може да се деинсталира."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Приложението се изисква от администратора на у-вото и не може да се деинсталира."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Управление на прилож. за администриране на у-вото"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Управление на потребителите"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се деинсталира."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"При синтактичния анализ на пакета възникна проблем."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Нови"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Всички"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Поверителност"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Достъп до у-вото"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Тази актуализация не изисква нови разрешения."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Отказване"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Още информация"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Отказване въпреки това"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> от <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Разрешаване на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Винаги ли да се разрешава на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Само при използване на приложението"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Винаги"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Отказване, без повторно запитване"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Деактивирахте <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"всички са деактивирани"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"няма деактивирани"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Разрешаване"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Приложения"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Разрешения за приложения"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Без повторно питане"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Няма разрешения"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Допълнителни разрешения"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Отваряне на информацията за приложението"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Още <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Още <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Това приложение е създадено за по-стара версия на Android. То може да спре да функционира нормално при отказване на разрешението."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"извършване на неизвестно действие"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> от <xliff:g id="COUNT_1">%2$d</xliff:g> приложения имат разрешение"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Системни приложения"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Скриване на системните"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Няма приложения"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Настройки за местоположението"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> е доставчик на услуги за местоположението за това устройство. Достъпът до местоположението може да бъде променен от съответните настройки."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ако откажете това разрешение, основни функции на устройството ви може да спрат да работят както трябва."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Наложено чрез правило"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Достъпът на заден план е деактивиран от правилата"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Достъпът на заден план е активиран от правилата"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Достъпът на преден план е активиран от правилата"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролира се от администратор"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Винаги"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Само при използване на прилож."</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Никога"</string>
+ <string name="loading" msgid="7811651799620593731">"Зарежда се…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Всички разрешения"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Други възможности на приложението"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Заявка за разрешение"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Открито е екранно наслагване"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"За да промените настройката за това разрешение, трябва първо да изключите екранното наслагване от „Настройки“ > „Приложения“"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Отваряне на настройките"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Действията инсталиране и деинсталиране не се поддържат на устройства с Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Изберете до какво да има достъп <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Приложението <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> е актуализирано. Изберете до какво да има достъп."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Отказ"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Напред"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Нови разрешения"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Текущи разрешения"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Приложението се подготвя…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Неизвестно"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"От съображения за сигурност на таблета ви не могат да се инсталират неизвестни приложения от този източник."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"От съображения за сигурност на телевизора ви не могат да се инсталират неизвестни приложения от този източник."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"От съображения за сигурност на телефона ви не могат да се инсталират неизвестни приложения от този източник."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефонът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телефона или загуба на информация вследствие на използването на приложението."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таблетът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на таблета или загуба на информация вследствие на използването на приложението."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Телевизорът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телевизора или загуба на информация вследствие на използването на приложението."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Напред"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Настройки"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Инсталир./деинсталир. на прилож. за Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bn-television/strings.xml b/packages/PackageInstaller/res/values-bn-television/strings.xml
new file mode 100644
index 0000000..a83d7b8
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bn-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"অস্বীকার করুন এবং আবার জিজ্ঞাসা করবেন না"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"আপনি সেটিংস > অ্যাপ্লিকেশান এ এটি পরে পরিবর্তন করতে পারেন"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"সিস্টেম অ্যাপ্লিকেশানগুলি দেখান"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"অ্যাপ্লিকেশনের অনুমতি"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"অ্যাপ্লিকেশনের অনুমতি"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> অনুমতিগুলি"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"অতিরিক্ত অনুমতিগুলি"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> অনুমতিগুলি"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bn-watch/strings.xml b/packages/PackageInstaller/res/values-bn-watch/strings.xml
new file mode 100644
index 0000000..79a91f4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bn-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"অস্বীকার করুন, আবার জিজ্ঞাসা করবেন না"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"সিস্টেম অ্যাপ্লিকেশানগুলি দেখান"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"পরিবর্তন করা যাবে না"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"হ্যাঁ"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"বাতিল করুন"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
new file mode 100644
index 0000000..c66f5bb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"প্যাকেজ ইনস্টলার"</string>
+ <string name="next" msgid="3057143178373252333">"পরবর্তী"</string>
+ <string name="install" msgid="5896438203900042068">"ইনস্টল করুন"</string>
+ <string name="done" msgid="3889387558374211719">"সম্পন্ন হয়েছে"</string>
+ <string name="cancel" msgid="8360346460165114585">"বাতিল করুন"</string>
+ <string name="installing" msgid="8613631001631998372">"ইনস্টল করা হচ্ছে…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ইন্সটল করা হচ্ছে…"</string>
+ <string name="install_done" msgid="3682715442154357097">"অ্যাপ্লিকেশান ইনস্টল করা হয়েছে৷"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"আপনি কি এই অ্যাপ্লিকেশানটি ইনস্টল করতে চান? এর মাধ্যমে যেসব জিনিস অ্যাক্সেস করার সুবিধা পাবেন সেগুলি হল:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"আপনি কি এই অ্যাপ্লিকেশানটি ইনস্টল করতে চান? এর জন্য কোনো বিশেষ অ্যাক্সেসের প্রয়োজন নেই৷"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"আপনি কি এই বিদ্যমান অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এই আপডেট হওয়া অ্যাপ্লিকেশানটির মাধ্যমে যেসব জিনিস অ্যাক্সেস করার সুবিধা পাবেন সেগুলি হল:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"আপনি কি এই ভেতরে থাকা অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এই আপডেট হওয়া অ্যাপ্লিকেশানটির মাধ্যমে যেসব জিনিস অ্যাক্সেস করার সুবিধা পাবেন সেগুলি হল:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"আপনি কি এই বিদ্যমান অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এর জন্য কোনো বিশেষ অ্যাক্সেসের প্রয়োজন নেই৷"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"আপনি কি ভেতরে থাকা অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এর জন্য কোনো বিশেষ অ্যাক্সেসের প্রয়োজন নেই৷"</string>
+ <string name="install_failed" msgid="6579998651498970899">"অ্যাপ্লিকেশান ইনস্টল করা হয়নি৷"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ইনস্টল হওয়া থেকে প্যাকেজটিকে অবরুদ্ধ করা হয়েছে।"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"কোনো বিদ্যমান প্যাকেজের সাথে এই প্যাকেজটির বিবাদ থাকার ফলে অ্যাপ ইনস্টল করা হয়নি৷"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"অ্যাপটি আপনার ট্যাবলেটের জন্য উপযুক্ত না হওয়ার কারণে এটি ইনস্টল করা হয়নি৷"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"এই অ্যাপ্লিকেশানটি আপনার টিভির জন্য উপযুক্ত নয়৷"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"অ্যাপটি আপনার ফোনের জন্য উপযুক্ত না হওয়ার কারণে এটি ইনস্টল করা হয়নি৷"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"প্যাকেজটি অবৈধ বলে মনে হওয়ার কারণে অ্যাপ ইনস্টল করা হয়নি৷"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> আপনার ট্যাবলেটে ইনস্টল করা যায়নি৷"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>-কে আপনার টিভিতে ইনস্টল করা যাবে না৷"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> আপনার ফোনে ইনস্টল করা যায়নি৷"</string>
+ <string name="launch" msgid="4826921505917605463">"খুলুন"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"আপনার প্রশাসক অজানা উৎস থেকে প্রাপ্ত অ্যাপ ইনস্টল করার অনুমতি দেয় না"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"এই ব্যবহারকারী অজানা অ্যাপ ইনস্টল করতে পারবেন না"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"এই ব্যবহারকারী অ্যাপ ইনস্টল করার অনুমতি পাননি"</string>
+ <string name="ok" msgid="3468756155452870475">"ঠিক আছে"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"অ্যাপ্লিকেশানগুলির পরিচালনা করুন"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"পর্যাপ্ত জায়গা খালি নেই"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ইনস্টল করা যায়নি৷ কিছু পরিমাণ জায়গা খালি করে আবার চেষ্টা করুন৷"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"অ্যাপ্লিকেশান পাওয়া যায়নি"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"অ্যাপ্লিকেশানটিকে ইনস্টল করা অ্যাপ্লিকেশানের তালিকাতে পাওয়া যায়নি৷"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"অনুমোদিত নয়"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"বর্তমান ব্যবহারকারী এই আনইনস্টলের কাজটি করার জন্য অনুমোদিত নয়৷"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ত্রুটি"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"অ্যাপ আনইনস্টল করা গেল না৷"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"অ্যাপ্লিকেশানটিকে আনইনস্টল করুন"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"আপডেট আনইনস্টল করুন"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> হল নিম্নলিখিত অ্যাপ্লিকেশানগুলির অংশ বিশেষ:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"আপনি কি এই অ্যাপ্লিকেশানটিকে আনইনস্টল করতে চান?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"আপনি কি "<b>"সমস্ত"</b>" ব্যবহারকারীর জন্য এই অ্যাপ্লিকেশানটিকে আনইনস্টল করতে চান? এই ডিভাইসের "<b>"সমস্ত"</b>" ব্যবহারকারীর কাছ থেকে অ্যাপ্লিকেশানটি ও এর ডেটা হারিয়ে যাবে৷"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"আপনি কি ব্যবহারকারী <xliff:g id="USERNAME">%1$s</xliff:g> এর জন্য এই অ্যাপ্লিকেশানটি আনইনস্টল করতে চান?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ফ্যাক্টরি সংস্করণের সাথে এই অ্যাপটিকে বদলাবেন? সব ডেটা মুছে যাবে।"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ফ্যাক্টরি সংস্করণের সাথে এই অ্যাপটিকে বদলাবেন? সমস্ত ডেটা মুছে যাবে। এটি এই ডিভাইসের সমস্ত ব্যবহারকারী সহ তাদের কার্যের প্রোফাইলের উপরেও প্রভাব ফেলবে।"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"এগুলি আনইনস্টল করা হচ্ছে"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"এগুলি আনইনস্টল করা যায়নি"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"আনইনস্টল করা হচ্ছে ..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হচ্ছে…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"আনইনস্টল সমাপ্ত হয়েছে৷"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হয়েছে"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"আনইনস্টল সফল হয়নি৷"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা গেল না৷"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"সক্রিয় থাকা ডিভাইস প্রশাসক অ্যাপটি আনইনস্টল করা যাবে না"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> এর সক্রিয় থাকা ডিভাইস প্রশাসক অ্যাপটি আনইনস্টল করা যাবে না"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"কিছু ব্যবহারকারী বা প্রোফাইলের জন্য এই অ্যাপ্লিকেশানটি আবশ্যক এবং অন্যদের জন্য আনইনস্টল করা হবে"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"আপনার প্রোফাইলের জন্য এই অ্যাপ্লিকেশানটি প্রয়োজন এবং এটিকে আনইনস্টল করা যাবে না৷"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"আপনার ডিভাইস প্রশাসকের চাহিদা অনুযায়ী এই অ্যাপ্লিকেশানটি আবশ্যক এবং এটি আনইনস্টল করা যাবে না।"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ডিভাইস প্রশাসক অ্যাপগুলি পরিচালনা করুন"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ব্যবহারকারীদের পরিচালনা করুন"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> আনইনস্টল করা যায়নি৷"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"প্যাকেজটি বিশ্লেষণ করার ক্ষেত্রে একটি সমস্যা হয়েছে৷"</string>
+ <string name="newPerms" msgid="6039428254474104210">"নতুন"</string>
+ <string name="allPerms" msgid="1024385515840703981">"সমস্ত"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"গোপনীয়তা"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ডিভাইসের অ্যাক্সেস"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"এই আপডেটের জন্য কোনো নতুন অনুমতির প্রয়োজন নেই৷"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"প্রত্যাখ্যান করুন"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"আরও তথ্য"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"যাইহোক অস্বীকার করুন"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> এর <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>কে <xliff:g id="ACTION">%2$s</xliff:g> এর অনুমতি দেবেন?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<xliff:g id="ACTION">%2$s</xliff:g>-এ সবসময় <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> অনুমতি দেবেন?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"অ্যাপটি ব্যবহার করার সময়"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"সবসময়"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"অস্বীকার করুন এবং আবার জিজ্ঞাসা করবেন না"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>টি অক্ষম করা হয়েছে"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"সমস্ত অক্ষম করা হয়েছে"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"কোনো কিছুই অক্ষম করা হয়নি"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"অনুমতি দিন"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"অ্যাপ"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"অ্যাপ্লিকেশনের অনুমতি"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"আর জিজ্ঞাসা করবেন না"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"কোনো অনুমতি নেই"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"অতিরিক্ত অনুমতিগুলি"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"অ্যাপের তথ্য দেখুন"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">আরও <xliff:g id="COUNT_1">%1$d</xliff:g>টি</item>
+ <item quantity="other">আরও <xliff:g id="COUNT_1">%1$d</xliff:g>টি</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"একটি পুরোনো সংস্করণের Android এর জন্য এই অ্যাপ্লিকেশানটি ডিজাইন করা হয়েছিল৷ অনুমতি অস্বীকার করলে এটিকে যে কাজের উদ্দেশ্যে তৈরি করা হয়েছিল সেটি নাও করতে পারে৷"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"কোনো অজানা কার্য সঞ্চালন করুন"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>টির মধ্যে <xliff:g id="COUNT_0">%1$d</xliff:g>টি অ্যাপ্লিকেশান মঞ্জুরিপ্রাপ্ত"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"সিস্টেম দেখুন"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"সিস্টেম লুকান"</string>
+ <string name="no_apps" msgid="1965493419005012569">"কোনো অ্যাপ্লিকেশান নেই"</string>
+ <string name="location_settings" msgid="1774875730854491297">"লোকেশন সেটিংস"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই ডিভাইসের জন্য একটি লোকেশন পরিষেবাগুলি প্রদান করে। লোকেশন সেটিংস থেকে লোকেশনের অ্যাক্সেস পরিবর্তন করা যায়।"</string>
+ <string name="system_warning" msgid="7103819124542305179">"আপনি যদি এই অনুমতিটি অস্বীকার করেন, তবে আপনার ডিভাইসের প্রাথমিক বৈশিষ্ট্যগুলিকে যে কাজের উদ্দেশ্যে তৈরি করা হয়েছিল সেগুলি নাও করতে পারে৷"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"নীতি দ্বারা প্রয়োগ করা হয়েছে"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"নীতির কারণে ব্যাকগ্রাউন্ড অ্যাক্সেস বন্ধ করা আছে"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"নীতির কারণে ব্যাকগ্রাউন্ড অ্যাক্সেস চালু করা আছে"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"নীতির কারণে খুলে রাখা অ্যাপের অ্যাক্সেস চালু করা আছে"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"অ্যাডমিনের দ্বারা নিয়ন্ত্রিত"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"সবসময়"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"অ্যাপটি ব্যবহার করার সময়"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"কখনও না"</string>
+ <string name="loading" msgid="7811651799620593731">"লোড হচ্ছে..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"সমস্ত অনুমতি"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"অন্যান্য অ্যাপ্লিকেশান ক্ষমতা"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"অনুমতির অনুরোধ"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"স্ক্রিন আচ্ছাদন শনাক্ত করা হয়েছে"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"এই অনুমতি সেটিংস পরিবর্তন করতে, আপনাকে প্রথমে সেটিংস > এ গিয়ে অ্যাপ্লিকেশানগুলি থেকে স্ক্রিন ওভারলে বন্ধ করতে হবে"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"সেটিংস খুলুন"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ওয়েরে ইনস্টল/আনইনস্টল করার কাজগুলি সমর্থিত নয়।"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> কে কোন জিনিসগুলিতে অ্যাক্সেস দেবেন তা বেছে নিন"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> আপডেট করা হয়েছে৷ এই অ্যাপ্লিকেশানটিকে কোন জিনিসগুলিতে অ্যাক্সেস দেবেন তা চয়ন করুন৷"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"বাতিল করুন"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"চালিয়ে যান"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"নতুন অনুমতিগুলি"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"বর্তমান অনুমতিগুলি"</string>
+ <string name="message_staging" msgid="6151794817691100003">"অ্যাপ্লিকেশান স্টেজ করা হচ্ছে..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"অজানা"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"আপনার নিরাপত্তার জন্য আপনার ট্যাবলেট কে এই উৎস থেকে আসা অজানা অ্যাপ ইনস্টল করার অনুমতি দেওয়া হয় না।"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"আপনার নিরাপত্তার জন্য আপনার TV কে এই উৎস থেকে আসা অজানা অ্যাপ ইনস্টল করার অনুমতি দেওয়া হয় না।"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"আপনার নিরাপত্তার জন্য আপনার ফোন কে এই উৎস থেকে আসা অজানা অ্যাপ ইনস্টল করার অনুমতি দেওয়া হয় না।"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"অজানা অ্যাপের দ্বারা আপনার ফোন এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হলেন যে এটি ব্যবহারের ফলে আপনার ফোনের বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"অজানা অ্যাপের দ্বারা আপনার ট্যাবলেট এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হলেন যে এটি ব্যবহারের ফলে আপনার ট্যাবলেটের বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"অজানা অ্যাপের দ্বারা আপনার টিভি এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হলেন যে এটি ব্যবহারের ফলে আপনার টিভি বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"চালিয়ে যান"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"সেটিংস"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"ওয়্যার অ্যাপ ইনস্টল/আনইনস্টল করা হচ্ছে"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bs-television/strings.xml b/packages/PackageInstaller/res/values-bs-television/strings.xml
new file mode 100644
index 0000000..564f2a6
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bs-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Odbij i ne pitaj ponovo"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Ovo možete kasnije promijeniti u odjeljku Postavke > Aplikacije"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Prikaži sistemske aplikacije"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Odobrenja za aplikacije"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Odobrenja za aplikacije"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Odobrenja za: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Dodatna odobrenja"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Odobrenja za: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bs-watch/strings.xml b/packages/PackageInstaller/res/values-bs-watch/strings.xml
new file mode 100644
index 0000000..dcae097
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bs-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Odbij i ne pitaj ponovo"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Prikaži sistemske aplikacije"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Ne mijenja se"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Da"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Otkaži"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
new file mode 100644
index 0000000..3f2c5c3
--- /dev/null
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Alat za instaliranje paketa"</string>
+ <string name="next" msgid="3057143178373252333">"Naprijed"</string>
+ <string name="install" msgid="5896438203900042068">"Instaliraj"</string>
+ <string name="done" msgid="3889387558374211719">"Gotovo"</string>
+ <string name="cancel" msgid="8360346460165114585">"Otkaži"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalacija u toku..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instaliranje <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikacija je instalirana."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Želite li instalirati ovu aplikaciju? Ona će dobiti pristup:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Želite li instalirati ovu aplikaciju? Ona ne zahtijeva poseban pristup."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Želite li ažurirati ovu postojeću aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija će dobiti pristup:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Želite li ažurirati ovu ugrađenu aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija će dobiti pristup:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Želite li ažurirati ovu postojeću aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Za ovo nije potreban poseban pristup."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Želite li ažurirati ovu ugrađenu aplikaciju? Vaš postojeći podaci neće biti izgubljeni. Nije potreban poseban pristup."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikacija nije instalirana."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Instaliranje ovog paketa je blokirano."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija nije instalirana jer paket nije usaglašen s postojećim paketom."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija nije instalirana jer nije kompatibilna s vašim tabletom."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ova aplikacija nije kompatibilna s vašim TV-om."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija nije instalirana jer nije kompatibilna s vašim telefonom."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija nije instalirana jer izgleda da paket nije važeći."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> ne možete instalirati na svoj tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na vaš TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> ne možete instalirati na svoj telefon."</string>
+ <string name="launch" msgid="4826921505917605463">"Otvori"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Vaš administrator ne dozvoljava instaliranje aplikacija iz nepoznatih izvora."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ovaj korisnik ne može instalirati nepoznate aplikacije."</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ovom korisniku nije dozvoljeno instaliranje aplikacija"</string>
+ <string name="ok" msgid="3468756155452870475">"Uredu"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Upravljaj aplikacijama"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nedostatak prostora"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Ne možete instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostora u pohrani i pokušajte ponovo."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacija nije pronađena"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacija nije pronađena na spisku instaliranih aplikacija."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nije dozvoljeno"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Trenutnom korisniku nije dozvoljeno da izvrši ovu deinstalaciju."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Greška"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nije bilo moguće deinstalirati aplikaciju."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uklanjanje aplikacije"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Uklanjanje ažuriranja"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je dio sljedeće aplikacije:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Želite li ukloniti ovu aplikaciju?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Želite li ukloniti ovu aplikaciju za "<b>" sve "</b>" korisnike? Aplikacija i njeni podaci će biti uklonjeni iz "<b>" svih "</b>" korisničkih računa na uređaju."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Želite li ukloniti ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni. To će utjecati na sve korisnike uređaja, uključujući i one s radnim profilima."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Tekuća deinstaliranja"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspjela deinstaliranja"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Uklanjanje u toku..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Deinstalacija paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Uklanjanje završeno."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Deinstaliran je paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Uklanjanje nije uspjelo."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspješno deinstaliran."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nije moguće deinstalirati aktivnu aplikaciju administratora uređaja"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nije moguće deinstalirati aktivnu aplikaciju administratora uređaja za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ova aplikacija je neophodna nekim korisnicima ili profilima, a kod ostalih je deinstalirana"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ova aplikacija je potrebna za vaš profil i ne može se deinstalirati."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ova aplikacija je potrebna administratoru vašeg uređaja i ne može se ukloniti."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Upravljajte aplikacijama administratora uređaja"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Upravljanje korisnicima"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> se ne može ukloniti."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Došlo je do problema prilikom raščlanjivanja paketa."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Sve"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privatnost"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Pristup uređaju"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Za ovo ažuriranje nisu potrebne nova odobrenja."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odbij"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Više informacija"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Odbij svakako"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Dozvoliti aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> da <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Uvijek dozvoliti da aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo dok se koristi aplikacija"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Uvijek"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odbij i ne pitaj ponovo"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"omogućeno je <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"sve je onemogućeno"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ništa nije onemogućeno"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dozvoli"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Odobrenja za aplikacije"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ne pitaj ponovo"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nema odobrenja"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Dodatna odobrenja"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvori informacije o aplikaciji"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ova aplikacija je kreirana za stariju verziju Androida. Odbijanje odobrenja može uzrokovati da ona više ne funkcionira onako kako je primarno zamišljeno."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"izvrši nepoznatu radnju"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Aplikacije sa odobrenjem: <xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Prikaži sistemske aplikacije"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Sakrij sistemske"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nijedna aplikacija"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Postavke lokacije"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> pruža usluge lokacije za ovaj uređaj. Pristup lokaciji se može izmijeniti u postavkama lokacije."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ukoliko odbijete ovo odobrenje, osnovne funkcije vašeg uređaja možda više neće funkcionirati onako kako je prvobitno zamišljeno."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Nametnuto je pravilima"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Pristup pozadini je onemogućen u skladu s pravilima"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Pristup pozadini je omogućen u skladu s pravilima"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Pristup u prvom planu je omogućen u skladu s pravilima"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolira administrator"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Uvijek"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo dok se koristi aplikacija"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nikada"</string>
+ <string name="loading" msgid="7811651799620593731">"Učitava se…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Sva odobrenja"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Ostale mogućnosti aplikacije"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Zahtjev za odobrenjem"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Otkriven je element koji prekriva sadržaj ekrana"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Da promijenite postavku ovog odobrenja, prvo morate isključiti element koji prekriva sadržaj ekrana u odjeljku Postavke > Aplikacije"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Otvori postavke"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instaliranje/deinstaliranje nije podržano na Wearu."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Odaberite čemu aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g>&Lt;/b> može pristupiti"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija &Lt;b><xliff:g id="APP_NAME">%1$s</xliff:g>&Lt;/b> je ažurirana. Odaberite čemu ova aplikacija može pristupiti."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Otkaži"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Nastavi"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nova odobrenja"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Postojeća odobrenja"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Aplikacija se postavlja…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Nepoznato"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Vašem tabletu iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Vašem TV-u iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Vašem telefonu iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Vaši podaci na telefonu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na telefonu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Vaši podaci na tabletu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na tabletu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Vaši podaci na TV-u i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na TV-u ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Nastavi"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Postavke"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"(De)instaliranje wear aplikacija"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ca-television/strings.xml b/packages/PackageInstaller/res/values-ca-television/strings.xml
new file mode 100644
index 0000000..7126c41
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ca-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Denega i no m\'ho tornis a preguntar"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Pots canviar-ho més endavant a Configuració > Aplicacions"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostra les aplicacions del sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Permisos d\'aplicacions"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Permisos d\'aplicacions"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Permisos: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Permisos addicionals"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Permisos: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ca-watch/strings.xml b/packages/PackageInstaller/res/values-ca-watch/strings.xml
new file mode 100644
index 0000000..d289b56
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ca-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Denega i no m\'ho demanis més"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostra les aplicacions del sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"No es pot canviar"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Sí"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancel·la"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml
new file mode 100644
index 0000000..62d758c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ca/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Instal·lador de paquets"</string>
+ <string name="next" msgid="3057143178373252333">"Següent"</string>
+ <string name="install" msgid="5896438203900042068">"Instal·la"</string>
+ <string name="done" msgid="3889387558374211719">"Fet"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancel·la"</string>
+ <string name="installing" msgid="8613631001631998372">"S\'està instal·lant..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"S\'està instal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplicació instal·lada."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Vols instal·lar aquesta aplicació? Tindrà els permisos següents:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vols instal·lar aquesta aplicació? No requereix cap accés especial."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Vols instal·lar una actualització per a aquesta aplicació? No es perdran les teves dades existents. L\'aplicació actualitzada tindrà els permisos següents:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vols instal·lar una actualització d\'aquesta aplicació integrada? No es perdran les teves dades. L\'aplicació actualitzada tindrà els permisos següents:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vols instal·lar una actualització a aquesta aplicació existent? Les dades existents no es perdran. No cal cap tipus d\'accés especial."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vols instal·lar una actualització a aquesta aplicació integrada? Les teves dades existents no es perdran. No cal cap tipus d\'accés especial."</string>
+ <string name="install_failed" msgid="6579998651498970899">"L\'aplicació no s\'ha instal·lat."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"El paquet s\'ha bloquejat perquè no es pugui instal·lar."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"L\'aplicació no s\'ha instal·lat perquè el paquet entra en conflicte amb un d\'existent."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"L\'aplicació no s\'ha instal·lat perquè no és compatible amb la teva tauleta."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aquesta aplicació no és compatible amb el teu televisor."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"L\'aplicació no s\'ha instal·lat perquè no és compatible amb el teu telèfon."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"L\'aplicació no s\'ha instal·lat perquè sembla que el paquet no és vàlid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut instal·lar a la tauleta."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut instal·lar al televisor."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut instal·lar al telèfon."</string>
+ <string name="launch" msgid="4826921505917605463">"Obre"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"L\'administrador no permet instal·lar aplicacions de fonts desconegudes"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aquest usuari no pot instal·lar aplicacions desconegudes"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Aquest usuari no té permís per instal·lar aplicacions"</string>
+ <string name="ok" msgid="3468756155452870475">"D\'acord"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gestiona les aplicacions"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Espai esgotat"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"No s\'ha pogut instal·lar <xliff:g id="APP_NAME">%1$s</xliff:g>. Allibera espai i torna-ho a provar."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"No s\'ha trobat l\'aplicació"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"No s\'ha trobat l\'aplicació a la llista d\'aplicacions instal·lades."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Sense autorització"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'usuari actual no té permís per dur a terme aquesta desinstal·lació."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"No s\'ha pogut desinstal·lar l\'aplicació."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstal·la l\'aplicació"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstal·la l\'actualització"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma part de l\'aplicació següent:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Vols desinstal·lar aquesta aplicació?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vols desinstal·lar aquesta aplicació per a "<b>"tots"</b>" els usuaris? L\'aplicació i les seves dades se suprimiran per a "<b>"tots"</b>" els usuaris del dispositiu."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vols desinstal·lar aquesta aplicació per a l\'usuari <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Si substitueixes aquesta aplicació per la versió de fàbrica, s\'esborraran totes les dades."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Si substitueixes aquesta aplicació per la versió de fàbrica, s\'esborraran totes les dades. Això afectarà tots els usuaris d\'aquest dispositiu, inclosos els que tinguin un perfil professional."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstal·lacions en curs"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstal·lacions fallides"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"S\'està desinstal·lant..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"S\'està desinstal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstal·lació finalitzada."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"S\'ha desinstal·lat <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"S\'ha produït un error en la desinstal·lació."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"No s\'ha pogut desinstal·lar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> correctament."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"No es pot desinstal·lar l\'aplicació activa de l\'administrador del dispositiu"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"No es pot desinstal·lar l\'aplicació activa de l\'administrador del dispositiu per a <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"L\'aplicació cal en alguns usuaris o perfils i s\'ha desinstal·lat per a d\'altres"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Aquesta aplicació es necessita per al teu perfil i no es pot desinstal·lar."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"L\'administrador del dispositiu necessita l\'aplicació i no la pots desinstal·lar."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gestiona aplicacions d\'administració del dispositiu"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gestiona els usuaris"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut desinstal·lar."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"S\'ha produït un problema en analitzar el paquet."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nous"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Tots"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privadesa"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Accés al dispositiu"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Aquesta actualització no requereix permisos nous."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Denega"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Més informació"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denega de totes maneres"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Vols permetre a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vols permetre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Només mentre s\'utilitzi l\'aplicació"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denega i no m\'ho tornis a preguntar"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> permisos desactivats"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"tots els permisos desactivats"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"cap permís desactivat"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permet"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicacions"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permisos d\'aplicacions"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"No m\'ho tornis a preguntar"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Sense permisos"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Més permisos"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Obre la informació de l\'aplicació"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> més</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> més</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Aquesta aplicació es va dissenyar per a una versió anterior d\'Android. És possible que no funcioni com està previst si li denegues el permís."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"dur a terme una acció desconeguda"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicacions permeses"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostra aplicacions del sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Amaga aplicacions del sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Cap aplicació"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Configuració d\'ubicació"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> és un proveïdor de serveis d\'ubicació per a aquest dispositiu. L\'accés a la ubicació es pot modificar des de la configuració d\'ubicació."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Si rebutges aquest permís, és possible que funcions bàsiques del dispositiu deixin de funcionar correctament."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicat en funció de la política"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"S\'ha desactivat l\'accés en segon pla per la política"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"S\'ha activat l\'accés en segon pla per la política"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"S\'ha activat l\'accés en primer pla per la política"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlat per l\'administrador"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Només mentre s\'utilitzi l\'app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Mai"</string>
+ <string name="loading" msgid="7811651799620593731">"S\'està carregant..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Tots els permisos"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Altres competències de l\'aplicació"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Sol·licitud de permís"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"S\'ha detectat una superposició de pantalla"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Per canviar la configuració de permisos, cal que desactivis la superposició de pantalla des de Configuració > Aplicacions"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Obre Configuració"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Les accions d\'instal·lar o de desinstal·lar no s\'admeten a Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Tria a què vols que tingui accés <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"S\'ha actualitzat <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Tria a què vols que tingui accés aquesta aplicació."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancel·la"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continua"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Permisos nous"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuals"</string>
+ <string name="message_staging" msgid="6151794817691100003">"S\'està preparant la instal·lació de l\'aplicació…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Desconegut"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Per seguretat, la tauleta no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Per seguretat, el televisor no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Per seguretat, el telèfon no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"El telèfon i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi al telèfon o de la pèrdua de dades que pugui resultar del seu ús."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"La tauleta i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi a la tauleta o de la pèrdua de dades que pugui resultar del seu ús."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"El televisor i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi al televisor o de la pèrdua de dades que pugui resultar del seu ús."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continua"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Configuració"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instal·lant o desinstal·lant aplicacions de Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-cs-television/strings.xml b/packages/PackageInstaller/res/values-cs-television/strings.xml
new file mode 100644
index 0000000..ed2d8dc
--- /dev/null
+++ b/packages/PackageInstaller/res/values-cs-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Odmítnout a již se neptat"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Svoji volbu můžete později změnit v nabídce Nastavení > Aplikace."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Zobrazit systémové aplikace"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Oprávnění aplikací"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Oprávnění aplikací"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> – oprávnění"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Další oprávnění"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> – oprávnění"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-cs-watch/strings.xml b/packages/PackageInstaller/res/values-cs-watch/strings.xml
new file mode 100644
index 0000000..160d7aa
--- /dev/null
+++ b/packages/PackageInstaller/res/values-cs-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Odmítnout a již se neptat"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Zobrazit systémové aplikace"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Nelze změnit"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ano"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Zrušit"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
new file mode 100644
index 0000000..a64c07a
--- /dev/null
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Nástroj k instalaci balíčků"</string>
+ <string name="next" msgid="3057143178373252333">"Další"</string>
+ <string name="install" msgid="5896438203900042068">"Instalovat"</string>
+ <string name="done" msgid="3889387558374211719">"Hotovo"</string>
+ <string name="cancel" msgid="8360346460165114585">"Zrušit"</string>
+ <string name="installing" msgid="8613631001631998372">"Probíhá instalace..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikace je nainstalována."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Chcete tuto aplikaci nainstalovat? Aplikace získá přístup k těmto oprávněním:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Chcete tuto aplikaci nainstalovat? Aplikace nevyžaduje žádná zvláštní oprávnění."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Chcete nainstalovat aktualizaci této existující aplikace? Stávající data nebudou ztracena. Aktualizovaná aplikace získá přístup k následujícímu:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Chcete nainstalovat aktualizaci této integrované aplikace? Stávající data nebudou ztracena. Aktualizovaná aplikace získá přístup k následujícímu:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Chcete nainstalovat aktualizaci této existující aplikace? Vaše existující data nebudou ztracena. Není vyžadován žádný zvláštní přístup."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Chcete nainstalovat aktualizaci této integrované aplikace? Vaše existující data nebudou ztracena. Není vyžadován žádný zvláštní přístup."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikaci nelze nainstalovat."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Instalace balíčku byla zablokována."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikaci nelze nainstalovat, protože balíček je v konfliktu se stávajícím balíčkem."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikaci nelze nainstalovat, protože s tabletem není kompatibilní."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Tato aplikace s vaší televizí není kompatibilní."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikaci nelze nainstalovat, protože s telefonem není kompatibilní."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikaci nelze nainstalovat, protože balíček zřejmě není platný."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> do tohoto tabletu nelze nainstalovat."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> se do televize nepodařilo nainstalovat."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> do tohoto telefonu nelze nainstalovat."</string>
+ <string name="launch" msgid="4826921505917605463">"Otevřít"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Váš administrátor nedovoluje instalaci aplikací z neznámých zdrojů"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Tento uživatel nemůže instalovat neznámé aplikace"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Tento uživatel nesmí instalovat aplikace"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Spravovat aplikace"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nedostatek místa"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> nelze nainstalovat. Uvolněte místo v paměti a zkuste to znovu."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikace nebyla nalezena"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikaci se nepodařilo najít na seznamu nainstalovaných aplikací."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Není povoleno"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Aktuální uživatel nemá k odinstalaci oprávnění."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Chyba"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikaci nelze odinstalovat."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Odinstalovat aplikaci"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Odinstalovat aktualizaci"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"Činnost <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je součástí následující aplikace:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Chcete tuto aplikaci odinstalovat?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Chcete tuto aplikaci odinstalovat "<b>"všem"</b>" uživatelům? Aplikace a její údaje budou odstraněny "<b>"všem"</b>" uživatelům tohoto zařízení."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Chcete tuto aplikaci pro uživatele <xliff:g id="USERNAME">%1$s</xliff:g> odinstalovat?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna. Tato akce ovlivní všechny uživatele zařízení, včetně uživatelů s pracovním profilem."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Probíhající odinstalace"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neúspěšné odinstalace"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Probíhá odinstalace..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Odinstalace byla dokončena."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Balíček <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> byl odinstalován"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Odinstalace se nezdařila."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se nezdařila."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktivní aplikaci pro správu zařízení nelze odinstalovat"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Aktivní aplikaci pro správu zařízení uživatele <xliff:g id="USERNAME">%1$s</xliff:g> nelze odinstalovat"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Tato aplikace je u některých uživatelů nebo profilů požadována, u ostatních byla odinstalována."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Tato aplikace je pro váš profil požadována a nelze ji odinstalovat."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Tato aplikace je administrátorem zařízení vyžadována a nelze ji odinstalovat."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Přejít do nastavení aplikací pro správu zařízení"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Správa uživatelů"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> nelze odinstalovat."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Při analýze balíčku došlo k chybě."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nově"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Vše"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Ochrana soukromí"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Přístup k zařízení"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Tato aktualizace nevyžaduje žádná nová oprávnění."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odmítnout"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Další informace"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Zamítnout"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> z <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Povolit aplikaci <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vždy povolit aplikaci <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Pouze při používání aplikace"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Vždy"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odmítnout a už se neptat"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"zakázáno (<xliff:g id="COUNT">%1$d</xliff:g>)"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"vše zakázáno"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nic nezakázáno"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Povolit"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikace"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Oprávnění aplikací"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Příště se neptat"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Žádná oprávnění"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Další oprávnění"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otevřít informace o aplikaci"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="few">Ještě <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Ještě <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Ještě <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Ještě <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Tato aplikace byla vytvořena pro starší verzi platformy Android. Pokud oprávnění neudělíte, může přestat fungovat podle původního záměru."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"provést neznámou akci"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Povoleno u <xliff:g id="COUNT_0">%1$d</xliff:g> z <xliff:g id="COUNT_1">%2$d</xliff:g> aplikací"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Zobrazit systémové aplikace"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Skrýt systémové aplikace"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Žádné aplikace"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Nastavení polohy"</string>
+ <string name="location_warning" msgid="8778701356292735971">"Služby určování polohy v tomto zařízení poskytuje aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>. Přístup k poloze lze upravit v nastavení polohy."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Pokud toto oprávnění zamítnete, základní funkce zařízení nemusejí fungovat správně."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Vynuceno zásadami"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Přístup na pozadí byl zakázán zásadami"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Přístup na pozadí byl povolen zásadami"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Přístup na popředí byl povolen zásadami"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Spravováno administrátorem"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Vždy"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Pouze při používání aplikace"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nikdy"</string>
+ <string name="loading" msgid="7811651799620593731">"Načítání…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Všechna oprávnění"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Ostatní oprávnění aplikace"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Žádost o oprávnění"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Byla zjištěna překryvná vrstva obrazovky"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Chcete-li změnit nastavení tohoto oprávnění, v Nastavení > Aplikace je třeba nejprve vypnout překryvnou vrstvu obrazovky"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Otevřít nastavení"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Akce instalace/odinstalace nejsou v zařízení Wear podporovány."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Určete, k čemu aplikaci <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> povolíte přístup"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikace <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> byla aktualizována. Určete, k čemu jí povolíte přístup."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Zrušit"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Pokračovat"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nová oprávnění"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Aktuální oprávnění"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Příprava instalace…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Neznámá aplikace"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Z bezpečnostních důvodů do tabletu není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Z bezpečnostních důvodů do televize není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Z bezpečnostních důvodů do telefonu není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na telefonu nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tablet a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na tabletu nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Televize a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na televizi nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Pokračovat"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Nastavení"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalace/odinstalace aplikací pro Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-da-television/strings.xml b/packages/PackageInstaller/res/values-da-television/strings.xml
new file mode 100644
index 0000000..f9c0da2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-da-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Afvis, og spørg ikke igen"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Du kan altid ændre dette i Indstillinger > Apps"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Vis systemapps"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Apptilladelser"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Apptilladelser"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g>-tilladelser"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Flere tilladelser"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g>-tilladelser"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-da-watch/strings.xml b/packages/PackageInstaller/res/values-da-watch/strings.xml
new file mode 100644
index 0000000..616b1c2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-da-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Afvis, og spørg ikke igen"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Vis systemapps"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Kan ikke ændres"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ja"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Annuller"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
new file mode 100644
index 0000000..73d03a5
--- /dev/null
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pakkeinstallationsprogram"</string>
+ <string name="next" msgid="3057143178373252333">"Næste"</string>
+ <string name="install" msgid="5896438203900042068">"Installer"</string>
+ <string name="done" msgid="3889387558374211719">"Afslut"</string>
+ <string name="cancel" msgid="8360346460165114585">"Annuller"</string>
+ <string name="installing" msgid="8613631001631998372">"Installerer..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Appen er installeret."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Vil du installere denne applikation? Den får adgang til følgende:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vil du installere denne applikation? Den kræver ingen særlig adgang."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Vil du installere en opdatering til den eksisterende app? Du mister ikke dine eksisterende data. Den opdaterede app kan gøre følgende:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vil du installere en opdatering til den indbyggede app? Du mister ikke dine eksisterende data. Den opdaterede app kan gøre følgende:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vil du installere en opdatering til denne eksisterende applikation? Dine eksisterende data vil ikke gå tabt. Det kræver ikke nogen særlig adgang."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vil du installere en opdatering til denne indbyggede applikation? Dine eksisterende data vil ikke gå tabt. Det kræver ikke nogen særlig adgang."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Appen blev ikke installeret."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Pakken blev blokeret i at blive installeret."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Appen blev ikke installeret, da pakken er i strid med en eksisterende pakke."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Appen blev ikke installeret, da den er ikke kompatibel med din tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Denne app er ikke kompatibel med dit fjernsyn."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Appen blev ikke installeret, da den ikke er kompatibel med din telefon."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Appen blev ikke installeret, da pakken ser ud til at være ugyldig."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på din tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på dit tv."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på din telefon."</string>
+ <string name="launch" msgid="4826921505917605463">"Åbn"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Din administrator tillader ikke installation af apps, der hentes fra ukendte kilder"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Denne bruger kan ikke installere ukendte apps"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Denne bruger har ikke tilladelse til at installere apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Administrer apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Der er ikke mere plads"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigør noget plads, og prøv igen."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Appen blev ikke fundet"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Appen blev ikke fundet på listen over installerede apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ikke tilladt"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Den nuværende bruger har ikke tilladelse til at udføre denne afinstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fejl"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Appen kunne ikke afinstalleres."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Afinstaller appen"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Afinstaller opdatering"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er en del af følgende app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Vil du afinstallere denne app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vil du afinstallere denne app for "<b>"alle"</b>" brugere? Applikationen og dens data vil blive fjernet fra "<b>"alle"</b>" brugere på denne enhed."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vil du afinstallere denne app for brugeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes. Dette påvirker alle brugere af denne enhed, herunder de brugere, der har arbejdsprofiler."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Igangværende afinstallationer"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislykkede afinstallationer"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Afinstallerer..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Afinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Afinstallationen er afsluttet."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> blev afinstalleret"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Afinstallationen mislykkedes."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kunne ikke afinstalleres."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Den aktive app til enhedsadministration kan ikke afinstalleres"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Den aktive app til enhedsadministration for <xliff:g id="USERNAME">%1$s</xliff:g> kan ikke afinstalleres"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Denne app kræves for nogle brugere eller profiler og afinstalleres for andre"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Denne app er nødvendig for din profil og kan ikke afinstalleres."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Denne app er påkrævet af din enhedsadministrator og kan ikke afinstalleres."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Administrer apps til enhedsadministration"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Administrer brugere"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke afinstalleres."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Der opstod et problem med parsing af pakken."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Ny"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privatliv"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Adgang til enheden"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Denne opdatering kræver ingen nye tilladelser."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Afvis"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Få flere oplysninger"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Afvis alligevel"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ud af <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Vil du give <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tilladelse til at <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Skal <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> altid have tilladelse til at <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Kun mens appen bruges"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Altid"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Afvis, og spørg ikke igen"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> er deaktiveret"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"alle er deaktiveret"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ingen er deaktiveret"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Tillad"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Apptilladelser"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Spørg ikke igen"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Ingen tilladelser"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Flere tilladelser"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Åbn appinfo"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> mere</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> mere</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Denne app er udviklet til en ældre version af Android. Hvis du ikke giver den tilladelse, vil den muligvis ikke længere virke efter hensigten."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"udføre en ukendt handling"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> ud af <xliff:g id="COUNT_1">%2$d</xliff:g> apps har tilladelse"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Vis systemapps"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Skjul systemapps"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Ingen apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Placeringsindstillinger"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> udbyder placeringstjenester for denne enhed. Adgangen til din placering kan ændres i Placeringsindstillinger."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Hvis du afviser denne tilladelse, vil grundlæggende funktioner på din enhed muligvis ikke længere fungere efter hensigten."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Håndhæves af politik"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Adgang i baggrunden er deaktiveret af en politik"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Adgang i baggrunden er aktiveret af en politik"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Adgang i forgrunden er aktiveret af en politik"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Styres af administratoren"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Altid"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Kun mens appen bruges"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Aldrig"</string>
+ <string name="loading" msgid="7811651799620593731">"Indlæser…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Alle tilladelser"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Andre app-egenskaber"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Anmodning om tilladelse"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Der er registreret skærmoverlejring"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Hvis du vil ændre denne indstilling for tilladelser, skal du først slå skærmoverlejringen fra i Indstillinger > Apps"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Åbn indstillingerne"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Det er ikke muligt at installere/afinstallere på Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Vælg, hvad <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> må få adgang til"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> er blevet opdateret. Vælg, hvad denne app må få adgang til."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Annuller"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Fortsæt"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nye tilladelser"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Aktuelle tilladelser"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Forbereder appen…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Ukendt"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Din tablet har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Dit fjernsyn har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Din telefon har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Din telefon og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din telefon eller tab af data, der kan skyldes brug af appen."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Din tablet og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din tablet eller tab af data, der kan skyldes brug af appen."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Dit fjernsyn og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på dit fjernsyn eller tab af data, der kan skyldes brug af appen."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Fortsæt"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Indstillinger"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installerer/afinstallerer Wear-apps"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-de-television/strings.xml b/packages/PackageInstaller/res/values-de-television/strings.xml
new file mode 100644
index 0000000..dc218e4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-de-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Ablehnen und nicht mehr fragen"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Du kannst dies später unter \"Einstellungen > Apps\" ändern."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"System-Apps anzeigen"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"App-Berechtigungen"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"App-Berechtigungen"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Berechtigungen für <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Zusätzliche Berechtigungen"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Berechtigungen für <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-de-watch/strings.xml b/packages/PackageInstaller/res/values-de-watch/strings.xml
new file mode 100644
index 0000000..5a0b8e1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-de-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Ablehnen & nicht mehr fragen"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"System-Apps anzeigen"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Keine Änderung möglich"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"\"Ja\""</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Abbrechen"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
new file mode 100644
index 0000000..5a05c0c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Paket-Installer"</string>
+ <string name="next" msgid="3057143178373252333">"Weiter"</string>
+ <string name="install" msgid="5896438203900042068">"Installieren"</string>
+ <string name="done" msgid="3889387558374211719">"Fertig"</string>
+ <string name="cancel" msgid="8360346460165114585">"Abbrechen"</string>
+ <string name="installing" msgid="8613631001631998372">"Wird installiert..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird installiert…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App wurde installiert."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Möchtest du diese App installieren? Sie erhält dann folgende Berechtigungen:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Möchtest du diese App installieren? Sie benötigt keinen besonderen Zugriff."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Möchtest du ein Update für diese vorhandene App installieren? Deine vorhandenen Daten bleiben erhalten. Die aktualisierte App erhält Zugriff auf:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Möchtest du ein Update für diese integrierte App installieren? Deine vorhandenen Daten bleiben erhalten. Die aktualisierte App erhält Zugriff auf:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Möchtest du ein Update für diese bestehende App installieren? Deine vorhandenen Daten bleiben erhalten. Die App benötigt keine besonderen Zugriffsrechte."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Möchtest du ein Update für diese integrierte App installieren? Deine vorhandenen Daten bleiben erhalten. Die App benötigt keine besonderen Zugriffsrechte."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App wurde nicht installiert."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Die Installation des Pakets wurde blockiert."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Die App wurde nicht installiert, da das Paket in Konflikt mit einem bestehenden Paket steht."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Die App wurde nicht installiert, da sie nicht mit deinem Tablet kompatibel ist."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Diese App ist nicht mit deinem Fernseher kompatibel."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Die App wurde nicht installiert, da sie nicht mit deinem Smartphone kompatibel ist."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Die App wurde nicht installiert, da das Paket offenbar ungültig ist."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Tablet installiert werden."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Fernseher installiert werden."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Telefon installiert werden."</string>
+ <string name="launch" msgid="4826921505917605463">"Öffnen"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Dein Administrator lässt keine Installationen von Apps aus unbekannten Quellen zu"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Dieser Nutzer darf keine unbekannten Apps installieren"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Dieser Nutzer darf keine Apps installieren"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Apps verwalten"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Kein freier Speicher vorhanden"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht installiert werden. Gib Speicherplatz frei und versuche es erneut."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App nicht gefunden"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Die App wurde nicht in der Liste der installierten Apps gefunden."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Keine Berechtigung"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Der aktuelle Nutzer ist nicht dazu berechtigt, diese Deinstallation auszuführen."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fehler"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"App konnte nicht deinstalliert werden."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"App deinstallieren"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Update deinstallieren"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> gehört zu folgender App:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Möchtest du diese App deinstallieren?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Möchtest du diese App für "<b>"alle"</b>" Nutzer entfernen? Die App und alle zugehörigen Daten werden für "<b>"alle"</b>" Nutzer des Geräts entfernt."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Möchtest du diese App für den Nutzer <xliff:g id="USERNAME">%1$s</xliff:g> deinstallieren?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt. Dies betrifft alle Nutzer des Geräts, einschließlich Arbeitsprofilen."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Laufende Deinstallationen"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Fehlgeschlagene Deinstallationen"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Wird deinstalliert..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird deinstalliert…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Deinstallation abgeschlossen"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalliert"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Deinstallation fehlgeschlagen"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Deinstallation von <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> fehlgeschlagen."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktive Apps zur Geräteverwaltung können nicht deinstalliert werden"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Die aktive App zur Geräteverwaltung kann nicht für <xliff:g id="USERNAME">%1$s</xliff:g> deinstalliert werden"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Diese App wird für einige Nutzer oder Profile benötigt und wurde für andere deinstalliert"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Diese App wird für dein Profil benötigt und kann nicht deinstalliert werden."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Die App wurde als obligatorisch festgelegt und kann nicht deinstalliert werden."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Apps zur Geräteverwaltung"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Nutzer verwalten"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht deinstalliert werden."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Beim Parsen des Pakets ist ein Problem aufgetreten."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Neu"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Datenschutz"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Gerätezugriff"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Für dieses Update sind keine neuen Berechtigungen erforderlich."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Ablehnen"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Weitere Informationen"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Trotzdem ablehnen"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> von <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Zulassen, dass die App <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g> darf?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> immer erlauben zu <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Nur während der App-Nutzung"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Immer"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Ablehnen und nicht mehr fragen"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> deaktiviert"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"Alle deaktiviert"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"Keine deaktiviert"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Zulassen"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"App-Berechtigungen"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Nicht mehr fragen"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Keine Berechtigungen"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Zusätzliche Berechtigungen"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"App-Info öffnen"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Noch <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Noch <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Diese App wurde für eine ältere Version von Android konzipiert. Wenn du keine Berechtigung erteilst, funktioniert die App möglicherweise nicht mehr ordnungsgemäß."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"Unbekannte Aktion durchführen"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> von <xliff:g id="COUNT_1">%2$d</xliff:g> Apps sind berechtigt."</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"System-Apps anzeigen"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"System ausblenden"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Keine Apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Standorteinstellungen"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist ein Anbieter von Standortdiensten für dieses Gerät. Die Berechtigungen für den Zugriff auf deinen Standort kannst du in den Standorteinstellungen ändern."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Wenn du diese Berechtigung deaktivierst, funktionieren grundlegende Funktionen deines Geräts möglicherweise nicht mehr ordnungsgemäß."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Von Richtlinien durchgesetzt"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Hintergrundzugriff aufgrund der Richtlinie deaktiviert"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Hintergrundzugriff aufgrund der Richtlinie aktiviert"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Vordergrundzugriff aufgrund der Richtlinie aktiviert"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Durch den Administrator verwaltet"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Immer"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Nur während der App-Nutzung"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nie"</string>
+ <string name="loading" msgid="7811651799620593731">"Wird geladen…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Alle Berechtigungen"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Andere App-Funktionen"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Berechtigungsanfrage"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Display-Overlay erkannt"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Um diese Berechtigungseinstellung zu ändern, musst du zunächst das Display-Overlay über \"Einstellungen\" > \"Apps\" deaktivieren."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Einstellungen öffnen"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Von Android Wear nicht unterstützte Aktionen installieren/deinstallieren."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Worauf darf die App <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> zugreifen?"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Die App <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> wurde aktualisiert. Worauf darf diese App zugreifen?"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Abbrechen"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Weiter"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Neue Berechtigungen"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Aktuelle Berechtigungen"</string>
+ <string name="message_staging" msgid="6151794817691100003">"App wird vorbereitet…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Unbekannt"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Aus Sicherheitsgründen kannst du auf dem Tablet keine unbekannten Apps aus dieser Quelle installieren."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Aus Sicherheitsgründen kannst du auf dem Fernseher keine unbekannten Apps aus dieser Quelle installieren."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Aus Sicherheitsgründen kannst du auf dem Smartphone keine unbekannten Apps aus dieser Quelle installieren."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Unbekannte Apps können gefährlich für dein Smartphone und deine personenbezogenen Daten sein. Indem du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Smartphone und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Unbekannte Apps können gefährlich für dein Tablet und deine personenbezogenen Daten sein. Indem du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Tablet und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Unbekannte Apps können gefährlich für deinen Fernseher und deine personenbezogenen Daten sein. Indem du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Fernseher und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Weiter"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Einstellungen"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear-Apps installieren/deinstallieren"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-el-television/strings.xml b/packages/PackageInstaller/res/values-el-television/strings.xml
new file mode 100644
index 0000000..44f77a9
--- /dev/null
+++ b/packages/PackageInstaller/res/values-el-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Απόρριψη και να μην ερωτηθώ ξανά"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Μπορείτε να το αλλάξετε αυτό αργότερα από το μενού Ρυθμίσεις > Εφαρμογές"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Εμφάνιση εφαρμογών συστήματος"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Άδειες εφαρμογών"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Άδειες εφαρμογών"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Άδειες - <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Πρόσθετες άδειες"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Άδειες - <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-el-watch/strings.xml b/packages/PackageInstaller/res/values-el-watch/strings.xml
new file mode 100644
index 0000000..3d923dc
--- /dev/null
+++ b/packages/PackageInstaller/res/values-el-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Απόρριψη και να μην ερωτηθώ ξανά"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Εμφάνιση εφαρμογών συστήματος"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Δεν είναι δυνατή η αλλαγή"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ναι"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Ακύρωση"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
new file mode 100644
index 0000000..707f7b1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Πρόγραμμα εγκατάστασης πακέτου"</string>
+ <string name="next" msgid="3057143178373252333">"Επόμενο"</string>
+ <string name="install" msgid="5896438203900042068">"Εγκατάσταση"</string>
+ <string name="done" msgid="3889387558374211719">"Τέλος"</string>
+ <string name="cancel" msgid="8360346460165114585">"Ακύρωση"</string>
+ <string name="installing" msgid="8613631001631998372">"Εγκατάσταση..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Εγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Εγκατάσταση εφαρμογής."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή; Θα έχει πρόσβαση σε:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή; Δεν απαιτείται οποιαδήποτε ειδική πρόσβαση."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Θέλετε να εγκαταστήσετε μια ενημέρωση σε αυτήν την υπάρχουσα εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Η ενημερωμένη εφαρμογή θα έχει πρόσβαση σε:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Θέλετε να εγκαταστήσετε μια ενημέρωση σε αυτήν την ενσωματωμένη εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Η ενημερωμένη εφαρμογή θα έχει πρόσβαση σε:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Θέλετε να εγκαταστήσετε μια ενημέρωση για αυτήν την υπάρχουσα εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Δεν απαιτείται ειδική πρόσβαση."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Θέλετε να εγκαταστήσετε μια ενημέρωση για αυτήν την ενσωματωμένη εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Δεν απαιτείται ειδική πρόσβαση."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Η εφαρμογή δεν έχει εγκατασταθεί."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Η εγκατάσταση του πακέτου αποκλείστηκε."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή το πακέτο έρχεται σε διένεξη με κάποιο υπάρχον πακέτο."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή δεν είναι συμβατή με το tablet που χρησιμοποιείτε."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Αυτή η εφαρμογή δεν είναι συμβατή με την τηλεόρασή σας."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή δεν είναι συμβατή με το τηλέφωνό σας."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή φαίνεται ότι το πακέτο δεν είναι έγκυρο."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g> στο tablet σας."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν ήταν δυνατό να εγκατασταθεί στην τηλεόρασή σας."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g> στο τηλέφωνό σας."</string>
+ <string name="launch" msgid="4826921505917605463">"Άνοιγμα"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ο διαχειριστής σας δεν επιτρέπει την εγκατάσταση εφαρμογών που προέρχονται από άγνωστες πηγές"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Δεν είναι δυνατή η εγκατάσταση άγνωστων εφαρμογών από αυτόν τον χρήστη"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Αυτός ο χρήστης δεν έχει δυνατότητα εγκατάστασης εφαρμογών."</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Διαχείριση εφαρμογών"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Δεν υπάρχει χώρος"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>. Απελευθερώστε λίγο χώρο και προσπαθήστε ξανά."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Δεν βρέθηκε εφαρμογή"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Η εφαρμογή δεν βρέθηκε στη λίστα με τις εγκατεστημένες εφαρμογές."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Δεν επιτρέπεται"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Δεν επιτρέπεται στον τρέχοντα χρήση να εκτελέσει την απεγκατάσταση."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Σφάλμα"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Δεν ήταν δυνατή η απεγκατάσταση της εφαρμογής."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Απεγκατάσταση εφαρμογής"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Απεγκατάσταση ενημέρωσης"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"Η δραστηριότητα <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> αποτελεί τμήμα της ακόλουθης εφαρμογής:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Θέλετε να καταργήσετε την εγκατάσταση αυτής της εφαρμογής;"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Θέλετε να καταργήσετε την εγκατάσταση αυτής της εφαρμογής για "<b>"όλους"</b>" τους χρήστες; Η εφαρμογή και τα δεδομένα της θα καταργηθούν από "<b>"όλους"</b>" τους χρήστες στη συσκευή."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Θέλετε να καταργήσετε την εγκατάσταση αυτής της εφαρμογής για το χρήστη <xliff:g id="USERNAME">%1$s</xliff:g>;"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Αντικατάσταση αυτής της εφαρμογής με την εργοστασιακή έκδοση; Όλα τα δεδομένα θα καταργηθούν."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Αντικατάσταση αυτής της εφαρμογής με την εργοστασιακή έκδοση; Όλα τα δεδομένα θα καταργηθούν. Αυτό επηρεάζει όλους τους χρήστες της συσκευής, συμπεριλαμβανομένων και αυτών με προφίλ εργασίας."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Απεγκαταστάσεις σε εξέλιξη"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Αποτυχημένες απεγκαταστάσεις"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Απεγκατάσταση..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Η κατάργηση εγκατάστασης ολοκληρώθηκε."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Απεγκαταστάθηκε <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Μη επιτυχής κατάργηση εγκατάστασης."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Επιτυχής απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Η κατάργ. εγκατάστ. της ενεργούς εφαρμογής διαχείρισης συσκευής δεν είναι δυνατή"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Η κατάργ. εγκατάστασης της ενεργούς εφαρμογής διαχείρισης συσκευής για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> δεν είναι δυνατή"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Η εφαρμογή απαιτείται για κάποιους χρήστες/προφίλ και απεγκαταστήθηκε για άλλους"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Αυτή η εφαρμογή απαιτείται για το προφίλ σας και δεν είναι δυνατή η απεγκατάστασή της."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Η εφαρμογή απαιτείται από το διαχειριστή και δεν είναι δυνατή η απεγκατάσταση."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Διαχείριση εφαρμογών διαχείρισης συσκευής"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Διαχείριση χρηστών"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Δεν ήταν δυνατή η κατάργηση της εγκατάστασης της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Παρουσιάστηκε ένα πρόβλημα κατά την ανάλυση του πακέτου."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Νέο"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Όλα"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Απόρρητο"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Πρόσβαση συσκευής"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Αυτή η ενημέρωση δεν απαιτεί νέες άδειες."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Απόρριψη"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Περισσότερες πληροφορίες"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Απόρριψη"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> από <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Να επιτρέπεται στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> να <xliff:g id="ACTION">%2$s</xliff:g>;"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Να επιτρέπεται πάντα στην εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> να <xliff:g id="ACTION">%2$s</xliff:g>;"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Μόνο κατά τη χρήση της εφαρμογής"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Πάντα"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Απόρριψη και να μην ερωτηθώ ξανά"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"έχουν απενεργοποιηθεί <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"έχουν απενεργοποιηθεί όλες"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"δεν έχει απενεργοποιηθεί καμία"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Να επιτρέπεται"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Εφαρμογές"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Δικαιώματα εφ/γών"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Να μην ερωτηθώ ξανά"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Χωρίς δικαιώματα"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Πρόσθετα δικαιώματα"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Άνοιγμα πληροφοριών εφαρμογής"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Ακόμα <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Ακόμα <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Αυτή η εφαρμογή σχεδιάστηκε για παλαιότερη έκδοση του Android. Η άρνηση άδειας μπορεί να έχει ως αποτέλεσμα να διακοπεί η κανονική λειτουργία της."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"εκτέλεση άγνωστης ενέργειας"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Επιτρέπονται <xliff:g id="COUNT_0">%1$d</xliff:g> από <xliff:g id="COUNT_1">%2$d</xliff:g> εφαρμογές"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Εμφάνιση συστήματος"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Απόκρυψη συστήματος"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Δεν υπάρχουν εφαρμογές"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Ρυθμίσεις τοποθεσίας"</string>
+ <string name="location_warning" msgid="8778701356292735971">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> είναι ο πάροχος των υπηρεσιών τοποθεσίας για τη συγκεκριμένη συσκευή. Μπορείτε να τροποποιήσετε την πρόσβαση τοποθεσίας από τις ρυθμίσεις τοποθεσίας."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Εάν αρνηθείτε να παραχωρήσετε αυτήν την άδεια, η λειτουργία ορισμένων βασικών δυνατοτήτων ενδέχεται να μην είναι η αναμενόμενη."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Επιβάλλεται από την πολιτική"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Η πρόσβαση στο παρασκήνιο απενενεργοποιήθηκε βάσει πολιτικής"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Η πρόσβαση στο παρασκήνιο ενεργοποιήθηκε βάσει πολιτικής"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Η πρόσβαση στο προσκήνιο ενεργοποιήθηκε βάσει πολιτικής"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Ελέγχεται από τον διαχειριστή"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Πάντα"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Μόνο κατά τη χρήση της εφαρμ."</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Ποτέ"</string>
+ <string name="loading" msgid="7811651799620593731">"Γίνεται φόρτωση…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Όλα τα δικαιώματα"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Άλλες δυνατότητες εφαρμογής"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Αίτημα άδειας"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Εντοπίστηκε επικάλυψη οθόνης"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Για να αλλάξετε αυτή τη ρύθμιση άδειας, θα πρέπει πρώτα να απενεργοποιήσετε την επικάλυψη οθόνης από τις Ρυθμίσεις > Εφαρμογές"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Άνοιγμα ρυθμίσεων"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Οι ενέργειες εγκατάστασης/απεγκατάστασης δεν υποστηρίζονται στο Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Επιλέξτε σε τι θα έχει πρόσβαση η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Η εφαρμογή <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ενημερώθηκε. Επιλέξτε σε τι θα έχει πρόσβαση αυτή η εφαρμογή."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Ακύρωση"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Συνέχεια"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Νέες άδειες"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Τρέχουσες άδειες"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Σταδιακή διάθεση εφαρμογής…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Άγνωστη"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στο tablet σας."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στην τηλεόρασή σας."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στο τηλέφωνό σας."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Το τηλέφωνό σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για οποιαδήποτε ζημιά στο τηλέφωνο ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Το tablet σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για οποιαδήποτε ζημιά στο tablet ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Η τηλεόρασή σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για οποιαδήποτε ζημιά στην τηλεόρασή ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Συνέχεια"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Ρυθμίσεις"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Εγκατάσταση/απεγκατάσταση εφαρμογών Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rAU-television/strings.xml b/packages/PackageInstaller/res/values-en-rAU-television/strings.xml
new file mode 100644
index 0000000..663e1d4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rAU-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Deny and don\'t ask again"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"You can change this later in Settings > Apps"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Show system apps"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"App permissions"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"App permissions"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Additional permissions"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rAU-watch/strings.xml b/packages/PackageInstaller/res/values-en-rAU-watch/strings.xml
new file mode 100644
index 0000000..e0d0edb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rAU-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Deny, don\'t ask again"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Show system apps"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Can\'t be changed"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Yes"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancel"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..ded57bb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Package installer"</string>
+ <string name="next" msgid="3057143178373252333">"Next"</string>
+ <string name="install" msgid="5896438203900042068">"Install"</string>
+ <string name="done" msgid="3889387558374211719">"Done"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
+ <string name="installing" msgid="8613631001631998372">"Installing…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App installed."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+ <string name="launch" msgid="4826921505917605463">"Open"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
+ <string name="newPerms" msgid="6039428254474104210">"New"</string>
+ <string name="allPerms" msgid="1024385515840703981">"All"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
+ <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
+ <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
+ <string name="loading" msgid="7811651799620593731">"Loading…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings > Apps"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what to allow this app to access."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rCA-television/strings.xml b/packages/PackageInstaller/res/values-en-rCA-television/strings.xml
new file mode 100644
index 0000000..663e1d4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rCA-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Deny and don\'t ask again"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"You can change this later in Settings > Apps"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Show system apps"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"App permissions"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"App permissions"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Additional permissions"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rCA-watch/strings.xml b/packages/PackageInstaller/res/values-en-rCA-watch/strings.xml
new file mode 100644
index 0000000..e0d0edb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rCA-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Deny, don\'t ask again"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Show system apps"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Can\'t be changed"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Yes"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancel"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..ded57bb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Package installer"</string>
+ <string name="next" msgid="3057143178373252333">"Next"</string>
+ <string name="install" msgid="5896438203900042068">"Install"</string>
+ <string name="done" msgid="3889387558374211719">"Done"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
+ <string name="installing" msgid="8613631001631998372">"Installing…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App installed."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+ <string name="launch" msgid="4826921505917605463">"Open"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
+ <string name="newPerms" msgid="6039428254474104210">"New"</string>
+ <string name="allPerms" msgid="1024385515840703981">"All"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
+ <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
+ <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
+ <string name="loading" msgid="7811651799620593731">"Loading…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings > Apps"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what to allow this app to access."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rGB-television/strings.xml b/packages/PackageInstaller/res/values-en-rGB-television/strings.xml
new file mode 100644
index 0000000..663e1d4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rGB-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Deny and don\'t ask again"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"You can change this later in Settings > Apps"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Show system apps"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"App permissions"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"App permissions"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Additional permissions"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rGB-watch/strings.xml b/packages/PackageInstaller/res/values-en-rGB-watch/strings.xml
new file mode 100644
index 0000000..e0d0edb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rGB-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Deny, don\'t ask again"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Show system apps"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Can\'t be changed"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Yes"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancel"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..ded57bb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Package installer"</string>
+ <string name="next" msgid="3057143178373252333">"Next"</string>
+ <string name="install" msgid="5896438203900042068">"Install"</string>
+ <string name="done" msgid="3889387558374211719">"Done"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
+ <string name="installing" msgid="8613631001631998372">"Installing…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App installed."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+ <string name="launch" msgid="4826921505917605463">"Open"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
+ <string name="newPerms" msgid="6039428254474104210">"New"</string>
+ <string name="allPerms" msgid="1024385515840703981">"All"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
+ <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
+ <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
+ <string name="loading" msgid="7811651799620593731">"Loading…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings > Apps"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what to allow this app to access."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rIN-television/strings.xml b/packages/PackageInstaller/res/values-en-rIN-television/strings.xml
new file mode 100644
index 0000000..663e1d4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rIN-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Deny and don\'t ask again"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"You can change this later in Settings > Apps"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Show system apps"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"App permissions"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"App permissions"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Additional permissions"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rIN-watch/strings.xml b/packages/PackageInstaller/res/values-en-rIN-watch/strings.xml
new file mode 100644
index 0000000..e0d0edb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rIN-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Deny, don\'t ask again"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Show system apps"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Can\'t be changed"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Yes"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancel"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..ded57bb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Package installer"</string>
+ <string name="next" msgid="3057143178373252333">"Next"</string>
+ <string name="install" msgid="5896438203900042068">"Install"</string>
+ <string name="done" msgid="3889387558374211719">"Done"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
+ <string name="installing" msgid="8613631001631998372">"Installing…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App installed."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+ <string name="launch" msgid="4826921505917605463">"Open"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
+ <string name="newPerms" msgid="6039428254474104210">"New"</string>
+ <string name="allPerms" msgid="1024385515840703981">"All"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
+ <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
+ <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
+ <string name="loading" msgid="7811651799620593731">"Loading…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings > Apps"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what to allow this app to access."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rXC-television/strings.xml b/packages/PackageInstaller/res/values-en-rXC-television/strings.xml
new file mode 100644
index 0000000..0f9eeb1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rXC-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Deny and don\'t ask again"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"You can change this later in Settings > Apps"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Show system apps"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"App permissions"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"App permissions"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Additional permissions"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> permissions"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rXC-watch/strings.xml b/packages/PackageInstaller/res/values-en-rXC-watch/strings.xml
new file mode 100644
index 0000000..89b2ea2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rXC-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Deny, don\'t ask again"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Show system apps"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Can\'t be changed"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Yes"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancel"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..ca392cc
--- /dev/null
+++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Package installer"</string>
+ <string name="next" msgid="3057143178373252333">"Next"</string>
+ <string name="install" msgid="5896438203900042068">"Install"</string>
+ <string name="done" msgid="3889387558374211719">"Done"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
+ <string name="installing" msgid="8613631001631998372">"Installing…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App installed."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+ <string name="launch" msgid="4826921505917605463">"Open"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem parsing the package."</string>
+ <string name="newPerms" msgid="6039428254474104210">"New"</string>
+ <string name="allPerms" msgid="1024385515840703981">"All"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
+ <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
+ <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
+ <string name="loading" msgid="7811651799620593731">"Loading…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings > Apps"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to access"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> has been updated. Choose what to allow this app to access."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling wear apps"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-es-rUS-television/strings.xml b/packages/PackageInstaller/res/values-es-rUS-television/strings.xml
new file mode 100644
index 0000000..e664dc2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-es-rUS-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Denegar el permiso y no volver a preguntar"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Puedes cambiar esta opción más tarde en Configuración > Aplicaciones"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostrar apps del sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Permisos de apps"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Permisos de apps"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Permisos de <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Permisos adicionales"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Permisos de <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-es-rUS-watch/strings.xml b/packages/PackageInstaller/res/values-es-rUS-watch/strings.xml
new file mode 100644
index 0000000..3880892
--- /dev/null
+++ b/packages/PackageInstaller/res/values-es-rUS-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Denegar y no preguntar más"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostrar apps del sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Inalterable"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Sí"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancelar"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..178f551
--- /dev/null
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Programa de instalación del paquete"</string>
+ <string name="next" msgid="3057143178373252333">"Siguiente"</string>
+ <string name="install" msgid="5896438203900042068">"Instalar"</string>
+ <string name="done" msgid="3889387558374211719">"Finalizado"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalando…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Se instaló la aplicación."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"¿Deseas instalar la aplicación? Esta tendrá acceso a lo siguiente:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"¿Deseas instalar esta aplicación? No requiere accesos especiales."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"¿Deseas instalar una actualización para esta aplicación? Tus datos no se perderán. La aplicación actualizada tendrá acceso a lo siguiente:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"¿Deseas instalar una actualización para esta aplicación integrada? Tus datos no se perderán. La aplicación actualizada tendrá acceso a lo siguiente:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"¿Quieres instalar una actualización de esta aplicación existente? Los datos existentes no se perderán. No se requiere ningún acceso especial."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"¿Quieres instalar una actualización de esta aplicación integrada? Los datos existentes no se perderán. No se requiere ningún acceso especial."</string>
+ <string name="install_failed" msgid="6579998651498970899">"No se instaló la aplicación."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Se bloqueó el paquete para impedir la instalación."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"No se instaló la app ya que está en conflicto con un paquete existente."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"No se instaló la app porque no es compatible con tu tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta app no es compatible con la TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"No se instaló la app porque no es compatible con tu teléfono."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"No se instaló la app porque parece que el paquete no es válido."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en tu tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en la TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en tu dispositivo."</string>
+ <string name="launch" msgid="4826921505917605463">"Abrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Tu administrador no permite la instalación de apps que se obtuvieron de fuentes desconocidas"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este usuario no puede instalar apps desconocidas"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuario no puede instalar apps"</string>
+ <string name="ok" msgid="3468756155452870475">"Aceptar"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Administrar aplicaciones"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sin espacio"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"No se encontró la aplicación."</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"La aplicación no se encontró en la lista de aplicaciones instaladas."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"No tiene permiso"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"El usuario actual no tiene permiso para llevar a cabo esta desinstalación."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"No se pudo desinstalar la app."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar la aplicación"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar la actualización"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> es parte de la siguiente aplicación:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"¿Deseas desinstalar esta aplicación?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"¿Quieres desinstalar esta aplicación para "<b>"todos"</b>" los usuarios? La aplicación y sus datos se eliminarán de "<b>"todos"</b>" los usuarios del dispositivo."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"¿Deseas desinstalar esta aplicación para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos. Esta acción afectará a todos los usuarios de este dispositivo, incluidos los que poseen perfiles de trabajo."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstalaciones activas"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstalaciones con errores"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Desinstalando…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"La desinstalación finalizó."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Se desinstaló <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Desinstalación incorrecta"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"No se pudo desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"No se puede desinstalar la app de administración activa del dispositivo"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"No se puede desinstalar la app de administración activa del dispositivo para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"App necesaria en algunos usuarios o perfiles, y desinstalada en otros"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Esta app es necesaria en tu perfil y no la puedes desinstalar."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"El admin. del dispositivo necesita esta aplicación y no se puede desinstalar."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Administrar apps del dispositivo del administrador"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Administrar usuarios"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"No se pudo desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Se produjo un error durante el análisis del paquete."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nuevo"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Todo"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacidad"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Acceso al dispositivo"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Esta actualización no requiere permisos nuevos."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Rechazar"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Más información"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denegar de todos modos"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"¿Quieres que la app de <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> realice la siguiente acción: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"¿Permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pueda <xliff:g id="ACTION">%2$s</xliff:g> siempre?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Solo cuando se usa la app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Siempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denegar el permiso y no volver a preguntar"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> inhabilitados"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"todos inhabilitados"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ninguno inhabilitado"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicaciones"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permisos de apps"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"No volver a preguntar"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Sin permisos"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Permisos adicionales"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir información de la app"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> más</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> más</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicación se diseñó para una versión de Android anterior. Si deniegas el permiso, es posible que deje de funcionar de la forma prevista."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"realizar una acción desconocida"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Se otorgó el permiso a <xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicaciones."</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Ninguna aplicación"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Configuración de la ubicación"</string>
+ <string name="location_warning" msgid="8778701356292735971">"La aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> provee servicios de ubicación a este dispositivo. El acceso a la ubicación puede modificarse desde la configuración de la ubicación."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Si no concedes este permiso, es posible que algunas funciones básicas del dispositivo dejen de funcionar correctamente."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Se aplica en función de la política"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acceso en segundo plano inhabilitado por la política"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acceso en segundo plano habilitado por la política"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acceso en primer plano habilitado por la política"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlado por el administrador"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Siempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Solo cuando se usa la app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
+ <string name="loading" msgid="7811651799620593731">"Cargando…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Todos los permisos"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Otras funciones de la aplicación"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Solicitud de permiso"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Se detectó una superposición de pantalla"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Para cambiar esta configuración de permisos, primero debes desactivar la superposición de pantalla en Configuración > Aplicaciones"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configuración"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear no admite las acciones de instalación y desinstalación"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Selecciona los permisos de acceso para <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Se actualizó <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Selecciona los permisos de acceso para esta app."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Permisos nuevos"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuales"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Preparando app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Desconocido"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Por tu seguridad, tu tablet no tiene permitido instalar apps desconocidas de esta fuente."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Por tu seguridad, tu TV no tiene permitido instalar apps desconocidas de esta fuente."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Por tu seguridad, tu teléfono no tiene permitido instalar apps desconocidas de esta fuente."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Tu teléfono y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra tu teléfono y la pérdida de datos que pueda ocasionar su uso."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tu tablet y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra tu tablet y la pérdida de datos que pueda ocasionar su uso."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tu TV y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra tu TV y la pérdida de datos que pueda ocasionar su uso."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Configuración"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps para Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-es-television/strings.xml b/packages/PackageInstaller/res/values-es-television/strings.xml
new file mode 100644
index 0000000..6a12063
--- /dev/null
+++ b/packages/PackageInstaller/res/values-es-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Denegar y no volver a preguntar"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Puedes cambiar esta opción más tarde en Ajustes > Aplicaciones."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostrar aplicaciones del sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Permisos de aplicaciones"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Permisos de aplicaciones"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Permisos: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Permisos adicionales"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Permisos: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-es-watch/strings.xml b/packages/PackageInstaller/res/values-es-watch/strings.xml
new file mode 100644
index 0000000..b3c4ff1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-es-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Denegar y no preguntar más"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostrar aplicaciones del sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"No se puede cambiar"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Sí"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancelar"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
new file mode 100644
index 0000000..bffaa0f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Instalador de paquetes"</string>
+ <string name="next" msgid="3057143178373252333">"Siguiente"</string>
+ <string name="install" msgid="5896438203900042068">"Instalar"</string>
+ <string name="done" msgid="3889387558374211719">"Listo"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalando…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplicación instalada"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"¿Quieres instalar esta aplicación? Tendrá los siguientes permisos:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"¿Quieres instalar esta aplicación? No requiere accesos especiales."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"¿Quieres instalar una actualización de la aplicación? Tus datos no se perderán. La aplicación actualizada podrá acceder a:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"¿Quieres instalar una actualización de esta aplicación integrada? Tus datos no se perderán. La aplicación actualizada podrá acceder a:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"¿Quieres instalar una actualización de esta aplicación? Tus datos no se perderán. No requiere ningún acceso especial."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"¿Quieres instalar una actualización de esta aplicación integrada? Tus datos no se perderán. No requiere ningún acceso especial."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplicación no instalada"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Se ha bloqueado la instalación del paquete."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"La aplicación no se ha instalado debido a un conflicto con un paquete actual."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"La aplicación no se ha instalado porque no es compatible con tu tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta aplicación no es compatible con tu TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"La aplicación no se ha instalado porque no es compatible con tu teléfono."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"La aplicación no se ha instalado porque parece que el paquete no es válido."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en el tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> no se ha podido instalar en tu TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en el teléfono."</string>
+ <string name="launch" msgid="4826921505917605463">"Abrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"El administrador no permite instalar aplicaciones de fuentes desconocidas"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este usuario no puede instalar aplicaciones desconocidas"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuario no tiene permiso para instalar aplicaciones"</string>
+ <string name="ok" msgid="3468756155452870475">"Aceptar"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Administrar aplicaciones"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sin espacio"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"No se ha podido instalar la aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplicación no encontrada"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"No se ha encontrado la aplicación en la lista de aplicaciones instaladas."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"No permitido"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"El usuario actual no puede iniciar el proceso de desinstalación."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"No se ha podido desinstalar la aplicación."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar aplicación"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar actualización"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma parte de esta aplicación:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"¿Quieres desinstalar esta aplicación?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"¿Quieres desinstalar esta aplicación para "<b>"todos"</b>" los usuarios? La aplicación y sus datos se eliminarán de "<b>"todos"</b>" los usuarios del dispositivo."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"¿Quieres desinstalar esta aplicación para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se eliminarán todos los datos."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se eliminarán todos los datos. Esto afecta a todos los usuarios del dispositivo, incluidos los que tienen perfiles de trabajo."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstalaciones en curso"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstalaciones fallidas"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Desinstalando..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstalación completada"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Se ha desinstalado <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Desinstalación correcta"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"No se ha podido desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"No se puede desinstalar la aplicación de administración de dispositivos activa"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"No se ha podido desinstalar la aplicación de administración de dispositivos activa de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplicación necesaria para algunos usuarios o perfiles y desinstalada en otros casos"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Esta aplicación es necesaria para tu perfil y no se puede desinstalar."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Esta aplicación es necesaria para el administrador de tu dispositivo y no se puede desinstalar."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gestionar aplicaciones de admón. de dispositivos"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Administrar usuarios"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"No se ha podido desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Se ha producido un error al analizar el paquete."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nuevo"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Todos"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacidad"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Acceso al dispositivo"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Esta actualización no requiere permisos nuevos."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Denegar"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Más información"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denegar de todos modos"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"¿Permitir a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"¿Quieres permitir siempre que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Solo mientras se usa la aplicación"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Siempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denegar y no volver a preguntar"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Inhabilitados: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"todos inhabilitados"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ninguno inhabilitado"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicaciones"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permisos de aplicaciones"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"No volver a preguntar"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Sin permisos"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Permisos adicionales"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir la información de la aplicación"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> más</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> más</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicación está diseñada para una versión anterior de Android. Si se le deniega el permiso, puede dejar de funcionar de la forma prevista."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"realizar una acción desconocida"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicaciones permitidas"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostrar aplicaciones del sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar aplicaciones del sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"No hay aplicaciones"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Ajustes de ubicación"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> es un proveedor de servicios de ubicación de este dispositivo. El acceso a la ubicación se puede modificar en los ajustes de ubicación."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Si rechazas este permiso, es posible que funciones básicas de tu dispositivo dejen de funcionar correctamente."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicado por política"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acceso en segundo plano inhabilitado por política"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acceso en segundo plano habilitado por política"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acceso en primer plano habilitado por política"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlado por el administrador"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Siempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Solo mientras se usa la app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
+ <string name="loading" msgid="7811651799620593731">"Cargando..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Todos los permisos"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Otras funciones de la aplicación"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Solicitud de permiso"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Superposición de pantalla detectada"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Para cambiar la configuración de este permiso, desactiva la superposición de pantalla en Ajustes > Aplicaciones"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir ajustes"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Las acciones de instalar y desinstalar no pueden realizarse en Wear"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Elige los permisos de acceso que quieres conceder a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> se ha actualizado. Elige los permisos de acceso que quieres conceder a esta aplicación."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Permisos nuevos"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuales"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Preparando aplicación…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Desconocido"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Por motivos de seguridad, tu tablet no puede instalar aplicaciones desconocidas de esta fuente."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Por motivos de seguridad, tu TV no puede instalar aplicaciones desconocidas de esta fuente."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Por motivos de seguridad, tu teléfono no puede instalar aplicaciones desconocidas de esta fuente."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Tu teléfono y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu teléfono o la pérdida de datos que se pueda derivar de su uso."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tu tablet y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu tablet o la pérdida de datos que se pueda derivar de su uso."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tu TV y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu TV o la pérdida de datos que se pueda derivar de su uso."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Ajustes"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps para Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-et-television/strings.xml b/packages/PackageInstaller/res/values-et-television/strings.xml
new file mode 100644
index 0000000..0abb2de
--- /dev/null
+++ b/packages/PackageInstaller/res/values-et-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Keela ja ära enam küsi"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Saate seda hiljem muuta jaotises Seaded > Rakendused"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Kuva süsteemirakendused"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Rakenduste load"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Rakenduste load"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> – load"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Lisaload"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> – load"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-et-watch/strings.xml b/packages/PackageInstaller/res/values-et-watch/strings.xml
new file mode 100644
index 0000000..328e215
--- /dev/null
+++ b/packages/PackageInstaller/res/values-et-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Keela, ära enam küsi"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Kuva süsteemirakendused"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Ei saa muuta"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Jah"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Tühista"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
new file mode 100644
index 0000000..1754411
--- /dev/null
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Paketiinstaller"</string>
+ <string name="next" msgid="3057143178373252333">"Järgmine"</string>
+ <string name="install" msgid="5896438203900042068">"Installi"</string>
+ <string name="done" msgid="3889387558374211719">"Valmis"</string>
+ <string name="cancel" msgid="8360346460165114585">"Tühista"</string>
+ <string name="installing" msgid="8613631001631998372">"Installimine ..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Paketi <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installimine …"</string>
+ <string name="install_done" msgid="3682715442154357097">"Rakendus on installitud."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Kas soovite rakenduse installida? See pääseb järgmiste üksuste juurde:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Kas soovite rakenduse installida? See ei nõua spetsiaalseid juurdepääsuõigusi."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Kas soovite olemasoleva rakenduse värskenduse installida? Teie olemasolevad andmed jäävad alles. Värskendatud rakendus pääseb järgmiste funktsioonide juurde:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Kas soovite sisseehitatud rakenduse värskenduse installida? Teie olemasolevad andmed jäävad alles. Värskendatud rakendus pääseb järgmiste funktsioonide juurde:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Kas soovite installida olemasoleva rakenduse värskenduse? Olemasolevad andmed ei lähe kaduma. See ei nõua erijuurdepääsu."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Kas soovite installida sisseehitatud rakenduse värskenduse? Olemasolevad andmed ei lähe kaduma. See ei nõua erijuurdepääsu."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Rakendus pole installitud."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paketi installimine blokeeriti."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Rakendust ei installitud, kuna pakett on olemasoleva paketiga vastuolus."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Rakendust ei installitud, kuna rakendus ei ühildu teie tahvelarvutiga."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Rakendus ei ühildu teie teleriga."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Rakendust ei installitud, kuna rakendus ei ühildu teie telefoniga."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Rakendust ei installitud, kuna pakett näib olevat sobimatu."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa teie tahvelarvutisse installida."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa teie telerisse installida."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa teie telefoni installida."</string>
+ <string name="launch" msgid="4826921505917605463">"Ava"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administraator ei luba installida tundmatutest allikatest pärinevaid rakendusi"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"See kasutaja ei saa installida tundmatuid rakendusi"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Kasutajal ei ole lubatud rakendusi installida"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Rakenduste haldamine"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Pole ruumi"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa installida. Vabastage mälu ja proovige uuesti."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Rakendust ei leitud"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Rakendust ei leitud installitud rakenduste loendist."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ei ole lubatud"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Praegusel kasutajal ei ole lubatud seda desinstallimist teha."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Viga"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Rakendust ei saanud desinstallida."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Rakenduse desinstallimine"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Värskenduse desinstallimine"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> on osa järgmisest rakendusest:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Kas soovite selle rakenduse desinstallida?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Kas soovite desinstallida selle rakenduse "<b>"kõikidelt"</b>" kasutajatelt? Rakendus ja selle andmed eemaldatakse "<b>"kõikidelt"</b>" seadme kasutajatelt."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Kas soovite kasutaja <xliff:g id="USERNAME">%1$s</xliff:g> puhul rakenduse desinstallida?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse. See mõjutab kõiki seadme kasutajaid, sh neid, kellel on tööprofiilid."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Käimasolevad desinstallimised"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ebaõnnestunud desinstallimised"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Desinstallimine ..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine …"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstallimine on lõpetatud."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Üksus <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on desinstallitud"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Desinstallimine ebaõnnestus."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine ebaõnnestus."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktiivset seadme administraatori rakendust ei saa desinstallida"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kasutaja <xliff:g id="USERNAME">%1$s</xliff:g> puhul ei saa aktiivset seadme administraatori rakendust desinstallida"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Rakendus on mõne kasutaja ja profiili puhul vajalik, teiste puhul see desinstalliti"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"See rakendus on vajalik teie profiili jaoks ja seda ei saa desinstallida."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Seadme administraator vajab seda rakendust ja seda ei saa desinstallida."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Halda seadme administraatori rakendusi"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Halda kasutajaid"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud desinstallida."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Probleem paketi sõelumisel."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Uus"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Kõik"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privaatsus"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Seadme juurdepääs"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"See värskendus ei nõua uusi lube."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Keela"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Lisateave"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Keela ikkagi"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-st"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Kas lubada rakendusel <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Kas lubada rakenduse puhul <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> alati toiming <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Ainult rakenduse kasutamise ajal"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Alati"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Keela ja ära enam küsi"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> on keelatud"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"kõik on keelatud"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"mitte ükski pole keelatud"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Luba"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Rakendused"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Rakenduste load"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ära enam küsi"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Lube ei ole"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Täiendavad load"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ava rakenduse teave"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Veel <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Veel <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Rakendus on mõeldud Androidi vanemale versioonile. Kui keeldute loa andmisest, ei pruugi see ootuspäraselt töötada."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"tundmatu toiming"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> rakendust <xliff:g id="COUNT_1">%2$d</xliff:g>-st on lubatud"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Kuva süsteem"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Peida süsteem"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Rakendusi pole"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Asukohaseaded"</string>
+ <string name="location_warning" msgid="8778701356292735971">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> on selle seadme asukohateenuste pakkuja. Asukoha juurdepääsu saab muuta asukohaseadetes."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Kui keelate loa, ei pruugi seadme põhifunktsioonid enam ootuspäraselt töötada."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Eeskirjadega jõustatud"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Reegli alusel on taustale juurdepääs keelatud"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Reegli alusel on taustale juurdepääs lubatud"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Reegli alusel on esiplaanile juurdepääs lubatud"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Juhib administraator"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Alati"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Ainult rakenduse kasutamisel"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Mitte kunagi"</string>
+ <string name="loading" msgid="7811651799620593731">"Laadimine ..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Kõik load"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Rakenduse muud funktsioonid"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Loa taotlus"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Tuvastati ekraani ülekate"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Selle loa seade muutmiseks peate esmalt välja lülitama ekraani ülekatte menüüs Seaded > Rakendused"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Ava seaded"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ei toeta installimist/desinstallimist."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Valige, millele lubate rakendusel <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> juurde pääseda"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Rakendust <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> värskendati. Valige, millele lubate sellel rakendusel juurde pääseda."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Tühista"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Jätka"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Uued load"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Praegused load"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Rakenduse ettevalmistamine …"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Tundmatu"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Teie turvalisuse huvides ei ole tahvelarvutil lubatud installida sellest allikast tundmatuid rakendusi."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Teie turvalisuse huvides ei ole TV-l lubatud installida sellest allikast tundmatuid rakendusi."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Teie turvalisuse huvides ei ole telefonil lubatud installida sellest allikast tundmatuid rakendusi."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Teie telefon ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate telefoni kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Teie tahvelarvuti ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate tahvelarvuti kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Teie teler ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate teleri kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Jätka"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Seaded"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Weari rak. installimine/desinstallimine"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-eu-television/strings.xml b/packages/PackageInstaller/res/values-eu-television/strings.xml
new file mode 100644
index 0000000..78fffae
--- /dev/null
+++ b/packages/PackageInstaller/res/values-eu-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Ukatu eta ez galdetu berriro"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Hori geroago alda dezakezu Ezarpenak > Aplikazioak atalean"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Erakutsi sistemaren aplikazioak"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Aplikazio-baimenak"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Aplikazio-baimenak"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> erabiltzeko baimenak"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Baimen gehigarriak"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> erabiltzeko baimenak"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-eu-watch/strings.xml b/packages/PackageInstaller/res/values-eu-watch/strings.xml
new file mode 100644
index 0000000..0f08cad
--- /dev/null
+++ b/packages/PackageInstaller/res/values-eu-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Ukatu; ez galdetu berriro"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Erakutsi sistemaren aplikazioak"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Ezin da aldatu"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Bai"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Utzi"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
new file mode 100644
index 0000000..0cb7e4c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pakete-instalatzailea"</string>
+ <string name="next" msgid="3057143178373252333">"Hurrengoa"</string>
+ <string name="install" msgid="5896438203900042068">"Instalatu"</string>
+ <string name="done" msgid="3889387558374211719">"Eginda"</string>
+ <string name="cancel" msgid="8360346460165114585">"Utzi"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalatzen…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> instalatzen…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikazioa instalatu da."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Aplikazioa instalatu nahi duzu? Elementu hauetarako sarbidea izango du:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Aplikazioa instalatu nahi duzu? Ez du sarbide berezirik behar."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Aplikazioaren eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Eguneratutako aplikazioak elementu hauetarako sarbidea izango du:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Aplikazio integratu honen eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Eguneratutako aplikazioak elementu hauetarako sarbidea izango du:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Aplikazioaren eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Ez du sarbide berezirik behar."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Aplikazio integratu honen eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Ez du sarbide berezirik behar."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Ez da aplikazioa instalatu."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Blokeatu egin da paketea instalatzeko aukera."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Ez da instalatu aplikazioa, gatazka bat sortu delako lehendik dagoen pakete batekin."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Ez da instalatu aplikazioa, ez delako tabletarekin bateragarria."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikazioa ez da telebistarekin bateragarria."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Ez da instalatu aplikazioa, ez delako telefonoarekin bateragarria."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Ez da instalatu aplikazioa, paketeak ez duelako balio."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> tabletan instalatu."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Ezin izan da instalatu <xliff:g id="APP_NAME">%1$s</xliff:g> telebistan."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> telefonoan instalatu."</string>
+ <string name="launch" msgid="4826921505917605463">"Ireki"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratzaileak ez du onartzen iturburu ezezagunetako aplikazioak instalatzea"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Erabiltzaile honek ezin ditu instalatu aplikazio ezezagunak"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Erabiltzaile honek ez du baimenik aplikazioak instalatzeko"</string>
+ <string name="ok" msgid="3468756155452870475">"Ados"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Kudeatu aplikazioak"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Ez dago behar adina toki"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> instalatu. Egin toki pixka bat eta saiatu berriro."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Ez da aplikazioa aurkitu"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikazioa ez da aurkitu instalatutako aplikazioen zerrendan."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ez dauka baimenik"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Erabiltzaile honek ez dauka desinstalatzeko baimenik."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Errorea"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Ezin izan da desinstalatu aplikazioa."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalatu aplikazioa"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalatu eguneratzea"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> aplikazio honen zati da:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Aplikazioa desinstalatu nahi duzu?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Aplikazioa erabiltzaile "<b>"guztientzat"</b>" desinstalatu nahi duzu? Aplikazioa eta bere datu guztiak gailuko erabiltzaile "<b>"guztiei"</b>" ezabatuko zaizkie."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> erabiltzailearen aplikazioa desinstalatu nahi duzu?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira. Gailuaren erabiltzaile guztiengan izango du eragina, laneko profilak dituztenengan barne."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Abian diren desinstalatze-eragiketak"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Huts egin duten desinstalatze-eragiketak"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Desinstalatzen…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalatzen…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstalatu da."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Desinstalatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Ezin izan da desinstalatu."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Ezin izan da desinstalatu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ezin da desinstalatu gailua administratzeko aplikazio aktiboa"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ezin da desinstalatu <xliff:g id="USERNAME">%1$s</xliff:g> erabiltzailearen gailua administratzeko aplikazio aktiboa"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Erabiltzaile edo profil batzuek behar dute aplikazio hau, baina desinstalatu egin da beste guztientzat."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Zure profilak behar du aplikazio hau eta ezin da desinstalatu."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Gailuaren administratzaileak aplikazio hori behar du eta ezin da desinstalatu."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Kudeatu gailua administratzeko aplikazioak"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Kudeatu erabiltzaileak"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> desinstalatu."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Arazo bat izan da paketea analizatzean."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Berriak"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Guztiak"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Pribatutasuna"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Gailurako sarbidea"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Eguneratze honek ez du baimen berririk behar."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Ukatu"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Informazio gehiago"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Ukatu hala ere"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari \"<xliff:g id="ACTION">%2$s</xliff:g>\" izeneko baimena eman nahi diozu?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Beti eman nahi diozu \"<xliff:g id="ACTION">%2$s</xliff:g>\" baimena <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioari?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Aplikazioa erabiltzean soilik"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Beti"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Baztertu eta ez galdetu berriro"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desgaituta"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"guztiak desgaituta"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"guztiak gaituta"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Baimendu"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikazioak"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Aplikazio-baimenak"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ez galdetu berriro"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Ez dago baimenik"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Baimen gehigarriak"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ireki aplikazioaren informazioa"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gehiago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gehiago</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Aplikazio hau Android-en bertsio zaharrago baterako diseinatuta dago. Baimena ukatzen baduzu, agian aurrerantzean ez du behar bezain ondo funtzionatuko."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"Gauzatu ekintza ezezagunak"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> aplikaziok dute baimena"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Erakutsi sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ezkutatu sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Ez dago aplikaziorik"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Kokapen-ezarpenak"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> gailu honen kokapen-zerbitzuen hornitzailea da. Kokapenerako sarbidea kokapen-ezarpenetatik alda daiteke."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Baimena ematen ez baduzu, baliteke gailuaren oinarrizko eginbide batzuek behar bezala ez funtzionatzea."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Gidalerroen bidez aplikatzen da"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Gidalerro batek eskatuta, atzeko planoa atzitzeko aukera desgaitu da"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Gidalerro batek eskatuta, atzeko planoa atzitzeko aukera gaitu da"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Gidalerro batek eskatuta, aurreko planoa atzitzeko aukera gaitu da"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Administratzaileak kontrolatzen du"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Beti"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Aplikazioa erabiltzean soilik"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Inoiz ez"</string>
+ <string name="loading" msgid="7811651799620593731">"Kargatzen…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Baimen guztiak"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Aplikazioaren beste gaitasun batzuk"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Baimen-eskaera"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Pantailaren gainjartzea detektatu da"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Baimen-ezarpen hau aldatzeko, pantailaren gainjartzea desaktibatu behar duzu Ezarpenak > Aplikazioak atalean"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Ireki ezarpenak"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instalatzeko eta desinstalatzeko ekintzak ezin dira gauzatu Wear gailuetan."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Aukeratu zer atzi dezakeen <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aplikazioak"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Eguneratu egin da <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Aukeratu aplikazioak zer atzi dezakeen."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Utzi"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Jarraitu"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Baimen berriak"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Uneko baimenak"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Aplikazioa prestatzen…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Ezezaguna"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Segurtasuna bermatzeko, tableta honetan ezin dira instalatu iturburu honetako aplikazio ezezagunak."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Segurtasuna bermatzeko, telebista honetan ezin dira instalatu iturburu honetako aplikazio ezezagunak."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Segurtasuna bermatzeko, telefono honetan ezin dira instalatu iturburu honetako aplikazio ezezagunak."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartzen duzu hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea zeu zarela."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartzen duzu hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea zeu zarela."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Iturburu honetako aplikazioak instalatzen badituzu, onartzen duzu haiek erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea zeu zarela."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Egin aurrera"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Ezarpenak"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear aplikazioak instalatzea/desinstalatzea"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fa-television/strings.xml b/packages/PackageInstaller/res/values-fa-television/strings.xml
new file mode 100644
index 0000000..95f2a54
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fa-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"اجازه ندارد و دیگر سؤال نشود"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"میتوانید بعداً آن را در تنظیمات > برنامهها تغییر دهید"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"نمایش برنامههای سیستم"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"مجوزهای برنامه"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"مجوزهای برنامه"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"مجوزهای <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"مجوزهای بیشتر"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"مجوزهای <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fa-watch/strings.xml b/packages/PackageInstaller/res/values-fa-watch/strings.xml
new file mode 100644
index 0000000..8d14954
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fa-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"رد شود، دیگر سؤال نشود"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"نمایش برنامههای سیستم"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"نمیتواند تغییر کند"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"بله"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"لغو"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
new file mode 100644
index 0000000..22f1a25
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"نصبکننده بسته"</string>
+ <string name="next" msgid="3057143178373252333">"بعدی"</string>
+ <string name="install" msgid="5896438203900042068">"نصب"</string>
+ <string name="done" msgid="3889387558374211719">"تمام"</string>
+ <string name="cancel" msgid="8360346460165114585">"لغو"</string>
+ <string name="installing" msgid="8613631001631998372">"در حال نصب…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"درحال نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"برنامه نصب شد."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"آیا میخواهید این برنامه را نصب کنید؟ این برنامه به این موارد دسترسی خواهد یافت:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"آیا میخواهید این برنامه را نصب کنید؟ این برنامه به دسترسی خاصی نیاز ندارد."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"آیا میٰخواهید بهٰروزرسانی این برنامه کنونی را نصب کنید؟ داده کنونی شما از بین نمیرود. برنامه بهروزرسانی شده دسترسی خواهد داشت به:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"آیا میخواهید بهروزرسانی این برنامه جاسازی شده را نصب کنید؟ دادههای کنونی شما از بین نمیرود. برنامه بهروزرسانی شده دسترسی خواهد داشت به:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"آیا میخواهید یک بهروزرسانی برای این برنامه کاربردی موجود نصب کنید؟ دادههای موجود شما از دست نخواهد رفت. به دسترسی ویژهای نیاز ندارد."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"آیا میخواهید یک بهروزرسانی برای این برنامه کاربردی داخلی نصب کنید؟ دادههای موجود شما از دست نخواهد رفت. به دسترسی ویژهای نیاز ندارد."</string>
+ <string name="install_failed" msgid="6579998651498970899">"برنامه نصب نشد."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"از نصب شدن بسته جلوگیری شد."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"برنامه نصب نشد چون بسته با بسته موجود تداخل دارد."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"برنامه نصب نشد چون با رایانه لوحیتان سازگار نیست."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"این برنامه با تلویزیون شما سازگار نیست."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"برنامه نصب نشد چون با تلفنتان سازگار نیست."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"برنامه نصب نشد چون به نظر میرسد بسته معتبر نیست."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> در رایانهٔ لوحی شما نصب نشد."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> را نمیتوان روی تلویزیون شما نصب کرد."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> در تلفن شما نصب نشد."</string>
+ <string name="launch" msgid="4826921505917605463">"باز کردن"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"سرپرست سیستم شما اجازه نمیدهد برنامههای دریافتشده از منابع ناشناس را نصب کنید"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"این کاربر نمیتواند برنامههای ناشناس نصب کند"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"این کاربر مجاز به نصب برنامه نیست"</string>
+ <string name="ok" msgid="3468756155452870475">"تأیید"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"مدیریت برنامهها"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"فضا کافی نیست"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> نصب نمیشود. مقداری از فضا را آزاد کرده و دوباره امتحان کنید."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"برنامه یافت نشد"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"برنامه در فهرست برنامههای نصب شده یافت نشد."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"مجاز نیست"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"کاربر کنونی مجاز به انجام این حذف نصب نیست."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"خطا"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"برنامه را نمیتوان حذف نصب کرد."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"حذف نصب برنامه"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"حذف نصب بهروزرسانی"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> قسمتی از برنامه زیر است:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"میخواهید این برنامه را حذف نصب کنید؟"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"آیا میخواهید این برنامه را برای "<b>"همه"</b>" کاربران حذف کنید؟ این برنامه کاربردی و دادههای آن برای "<b>"همه"</b>" کاربران این دستگاه حذف خواهد شد."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"آیا میخواهید این برنامه را برای این کاربر <xliff:g id="USERNAME">%1$s</xliff:g> حذف نصب کنید؟"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"این برنامه با نسخه کارخانه جایگزین شود؟ همه دادهها پاک میشوند."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"این برنامه با نسخه کارخانه جایگزین شود؟ همه دادهها پاک میشوند. این کار همه کاربران این دستگاه (از جمله کاربرانی که نمایه کاری دارند) را تحت تأثیر قرار خواهد داد."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"حذفنصبهای درحال انجام"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"حذفنصبهای ناموفق"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"در حال حذف نصب..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"درحال حذف نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"حذف نصب پایان یافت."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> را حذف نصب کرد"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"حذف نصب انجام نشد."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> باموفقیت حذف نصب شد."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"نمیتوان برنامه فعال سرپرست دستگاه را حذف نصب کرد"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"نمیتوان برنامه فعال سرپرست دستگاه را برای <xliff:g id="USERNAME">%1$s</xliff:g> حذف نصب کرد"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"این برنامه برای برخی کاربران یا نمایهها ضروری است و برای بقیه حذف نصب شد"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"این برنامه برای نمایه شما لازم است و نمیتوان آن را حذف نصب کرد."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"سرپرست دستگاه شما این برنامه را لازم کرده است و نمیتواند حذف نصب شود."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"مدیریت برنامههای سرپرست دستگاه"</string>
+ <string name="manage_users" msgid="3125018886835668847">"مدیریت کاربران"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> حذف نصب نشد."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"مشکلی در تجزیه این بسته وجود داشت."</string>
+ <string name="newPerms" msgid="6039428254474104210">"جدید"</string>
+ <string name="allPerms" msgid="1024385515840703981">"همه موارد"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"حریم خصوصی"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"دسترسی به دستگاه"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"این بهروزرسانی به مجوز جدیدی نیاز ندارد."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"اجازه ندارد"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"اطلاعات بیشتر"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"در هر صورت نادیده گرفته شود"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> از <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"به<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> اجازه <xliff:g id="ACTION">%2$s</xliff:g> را میدهید؟"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"همیشه به <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> برای <xliff:g id="ACTION">%2$s</xliff:g> اجازه داده شود؟"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"فقط هنگام استفاده از برنامه"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"همیشه"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"رد شود و دیگر سؤال نشود"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> مجوز غیرفعال هستند"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"همه مجوزها غیرفعال هستند"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"هیچ موردی غیرفعال نیست"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"مجاز است"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"برنامهها"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"مجوزهای برنامه"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"دوباره سؤال نشود"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"مجوزی موجود نیست"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"مجوزهای بیشتر"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"باز کردن اطلاعات برنامه"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد دیگر</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد دیگر</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"این برنامه برای یک نسخه قدیمیتر از Android طراحی شده بود. نپذیرفتن اجازه ممکن است باعث شود که برنامه دیگر به صورتی که موردنظر است کار نکند."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"انجام یک اقدام ناشناس"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> برنامه از <xliff:g id="COUNT_1">%2$d</xliff:g> برنامه مجاز است"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"نمایش سیستم"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"پنهان کردن سیستم"</string>
+ <string name="no_apps" msgid="1965493419005012569">"برنامهای موجود نیست"</string>
+ <string name="location_settings" msgid="1774875730854491297">"تنظیمات مکان"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> یکی از ارائهدهندگان سرویسهای مکان برای این دستگاه است. با رفتن به تنظیمات مکان میتوانید دسترسی به موقعیت مکانی را تغییر دهید."</string>
+ <string name="system_warning" msgid="7103819124542305179">"اگر این اجازه را رد کنید، ممکن است قابلیتهای اصلی دستگاهتان دیگر عملکرد موردانتظار را نداشته باشند."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"اجرا توسط خطمشی"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"دسترسی به پسزمینه بهموجب خطمشی غیرفعال شد"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"دسترسی به پسزمینه بهموجب خطمشی فعال شد"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"دسترسی به پیشزمینه بهموجب خطمشی فعال شد"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"توسط سرپرست سیستم کنترل میشود"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"همیشه"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"فقط هنگام استفاده از برنامه"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"هرگز"</string>
+ <string name="loading" msgid="7811651799620593731">"درحال بارگیری…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"همه مجوزها"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"سایر قابلیتهای برنامه"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"درخواست مجوز"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"همپوشانی صفحه شناسایی شد"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"برای تغییر این تنظیم مجوز، ابتدا باید همپوشانی صفحه را از «تنظیمات > برنامهها» خاموش کنید"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"باز کردن تنظیمات"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"کنشهای نصب/حذف نصب در Wear پشتیبانی نمیشود."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"انتخاب کنید <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> اجازه دارد به چه چیزی دسترسی پیدا کند"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> بهروزرسانی شده است. انتخاب کنید این برنامه اجازه دارد به چه چیزی دسترسی پیدا کند."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"لغو"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ادامه"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"مجوزهای جدید"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"مجوزهای کنونی"</string>
+ <string name="message_staging" msgid="6151794817691100003">"مرحلهبندی برنامه…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"نامشخص"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"برای امنیت شما، رایانه لوحیتان اجازه نمیدهد از این منبع برنامههای ناشناس نصب شوند."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"برای امنیت شما، تلویزیونتان اجازه نمیدهد از این منبع برنامههای ناشناس نصب شوند."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"برای امنیت شما، تلفنتان اجازه نمیدهد از این منبع برنامههای ناشناس نصب شوند."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"تلفن و دادههای شخصیتان در برابر حمله برنامههای ناشناس آسیبپذیرتر هستند. با نصب این برنامه، موافقت میکنید که مسئول هرگونه آسیب به تلفن یا از دست رفتن دادهای هستید که ممکن است در نتیجه استفاده از آن به وجود آید."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"رایانه لوحی و دادههای شخصیتان در برابر حمله برنامههای ناشناس آسیبپذیرتر هستند. با نصب این برنامه، موافقت میکنید که مسئول هرگونه آسیب به رایانه لوحی یا از دست رفتن دادهای هستید که ممکن است در نتیجه استفاده از آن به وجود آید."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"تلویزیون و دادههای شخصیتان در برابر حمله برنامههای ناشناس آسیبپذیرتر هستند. با نصب این برنامه، موافقت میکنید که مسئول هرگونه آسیب به تلویزیون یا از دست رفتن دادهای هستید که ممکن است در نتیجه استفاده از آن به وجود آید."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ادامه"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"تنظیمات"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"نصب/حذف نصب برنامههای پوشیدنی"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fi-television/strings.xml b/packages/PackageInstaller/res/values-fi-television/strings.xml
new file mode 100644
index 0000000..fbcbe4f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fi-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Hylkää äläkä kysy uudelleen"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Voit muuttaa tätä myöhemmin valitsemalla Asetukset > Sovellukset."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Näytä järjestelmäsovellukset"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Sovellusten käyttöoikeudet"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Sovellusten käyttöoikeudet"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Käyttöoikeudet – <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Lisäkäyttöoikeudet"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Käyttöoikeudet – <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fi-watch/strings.xml b/packages/PackageInstaller/res/values-fi-watch/strings.xml
new file mode 100644
index 0000000..292c417
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fi-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Hylkää, äläkä kysy uudelleen"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Näytä järjestelmäsovellukset"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Ei muutettavissa"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Kyllä"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Peruuta"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml
new file mode 100644
index 0000000..7ce75d1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fi/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Paketin asentaja"</string>
+ <string name="next" msgid="3057143178373252333">"Seuraava"</string>
+ <string name="install" msgid="5896438203900042068">"Asenna"</string>
+ <string name="done" msgid="3889387558374211719">"Valmis"</string>
+ <string name="cancel" msgid="8360346460165114585">"Peruuta"</string>
+ <string name="installing" msgid="8613631001631998372">"Asennetaan…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Asennetaan kohdetta <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Sovellus on asennettu."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Haluatko asentaa tämän sovelluksen? Se saa käyttöönsä seuraavat ominaisuudet:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Haluatko asentaa tämän sovelluksen? Se ei vaadi erityisiä käyttöoikeuksia."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Haluatko asentaa päivityksen tähän olemassa olevaan sovellukseen? Olemassa olevat tiedot eivät katoa. Päivitetty sovellus saa käyttöönsä seuraavat ominaisuudet:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Haluatko asentaa päivityksen tähän sisäiseen sovellukseen? Olemassa olevat tiedot eivät katoa. Päivitetty sovellus saa käyttöönsä seuraavat ominaisuudet:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Haluatko asentaa päivityksen tähän sovellukseen? Et menetä nykyisiä tietojasi. Päivitys ei edellytä erityisiä käyttöoikeuksia."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Haluatko asentaa päivityksen tähän laitteen mukana tulleeseen sovellukseen? Et menetä nykyisiä tietojasi. Päivitys ei edellytä erityisiä käyttöoikeuksia."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Sovellusta ei asennettu."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paketin asennus estettiin."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Sovellusta ei asennettu, koska paketti on ristiriidassa nykyisen paketin kanssa."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Sovellusta ei asennettu, koska se ei ole yhteensopiva tabletin kanssa."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Tämä sovellus ei ole yhteensopiva televisiosi kanssa."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Sovellusta ei asennettu, koska se ei ole yhteensopiva puhelimen kanssa."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Sovellusta ei asennettu, koska paketti vaikuttaa virheelliseltä."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen tähän tablet-laitteeseen epäonnistui."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei asennu televisioosi."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen puhelimeesi ei onnistunut."</string>
+ <string name="launch" msgid="4826921505917605463">"Avaa"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Järjestelmänvalvoja ei salli sovellusten asentamista tuntemattomista lähteistä."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Tämä käyttäjä ei voi asentaa tuntemattomia sovelluksia."</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Tämä käyttäjä ei voi asentaa sovelluksia."</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Hallinnoi sovelluksia"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Tallennustila loppu"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen epäonnistui. Vapauta tallennustilaa ja yritä uudelleen."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Sovellusta ei löydy"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Sovellusta ei löydy asennettujen sovelluksien luettelosta."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ei sallittu"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Nykyisellä käyttäjällä ei ole oikeutta suorittaa tätä poistoa."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Virhe"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Sovelluksen poistaminen epäonnistui."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Poista sovellus"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Poista päivitys"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> on osa seuraavaa sovellusta:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Haluatko poistaa tämän sovelluksen?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Haluatko poistaa tämän sovelluksen "<b>"kaikilta"</b>" käyttäjiltä? Sovellus ja sen tiedot poistetaan "<b>"kaikilta"</b>" laitteen käyttäjiltä."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Haluatko poistaa tämän sovelluksen käyttäjältä <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki tiedot poistetaan."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki tiedot poistetaan. Tämä vaikuttaa kaikkiin laitteen käyttäjiin, myös työprofiileihin."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Käynnissä olevat poistot"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Epäonnistuneet poistot"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Poistetaan..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Poistetaan pakettia <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Poisto valmis."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> poistettu"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Poisto epäonnistui."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on poistettu."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktiivista laitteenhallintasovellusta ei voi poistaa käytöstä."</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Käyttäjän <xliff:g id="USERNAME">%1$s</xliff:g> aktiivista laitteenhallintasovellusta ei voi poistaa käytöstä."</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Jotkin käyttäjät/profiilit tarvitsevat tätä sovellusta ja se poistettiin muista."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Profiilisi käyttö edellyttää tätä sovellusta. Sovellusta ei voi poistaa."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Laitteen järjestelmänvalvoja tarvitsee tätä sovellusta eikä sitä voi poistaa."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Hallinnoi laitteenhallintasovelluksia"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Hallinnoi käyttäjiä"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> poistaminen epäonnistui"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketin jäsentämisessä esiintyi ongelma."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Uusi"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Kaikki"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Tietosuoja"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Laitteen käyttö"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Tämä päivitys ei vaadi uusia käyttöoikeuksia."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Estä"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Lisätietoja"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Kiellä silti"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Saako <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Saako <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aina <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Vain sovelluksen käytön aikana"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Aina"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Hylkää äläkä kysy uudelleen"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> pois käytöstä"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"kaikki pois käytöstä"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"kaikki käytössä"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Salli"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Sovellukset"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Sovellusten käyttöoikeudet"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Älä kysy uudestaan"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Ei käyttöoikeuksia"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Lisäkäyttöoikeudet"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Avaa sovelluksen tiedot"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> lisää</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> lisää</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Tämä sovellus on suunniteltu vanhemmalle Android-versiolle. Se ei välttämättä toimi oikein, jos käyttöoikeuksia ei sallita."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"suorita tuntematon toiminto"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Sallitut sovellukset: <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Näytä järjestelmä"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Piilota järjestelmä"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Ei sovelluksia"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Sijaintiasetukset"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> on tämän laitteen sijaintipalveluiden tarjoaja. Sijainnin käyttöoikeutta voi muokata sijaintiasetuksissa."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Jos peruutat tämän käyttöoikeuden, laitteesi perustoiminnot eivät välttämättä enää toimi oikein."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Käytännön vahvistama"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Käytäntö estää taustakäytön"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Käytäntö sallii taustakäytön"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Käytäntö sallii käytön etualalla"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Järjestelmänvalvoja hallinnoi tätä"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Aina"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Vain sovelluksen käytön aikana"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Ei koskaan"</string>
+ <string name="loading" msgid="7811651799620593731">"Ladataan…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Kaikki käyttöoikeudet"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Muut sovellusluvat"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Lupapyyntö"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Näytön peittokuva havaittiin"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Ennen kuin voit muokata tätä käyttöoikeusasetusta, sinun täytyy poistaa näytön peittokuva käytöstä Asetukset-valikon Sovellukset-kohdasta."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Avaa Asetukset"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ei tue asennus- ja poistotoimintoja."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Valitse, mitä käyttöoikeuksia sovellukselle <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> myönnetään."</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> on päivitetty. Valitse, mitä käyttöoikeuksia tälle sovellukselle myönnetään."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Peruuta"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Jatka"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Uudet käyttöoikeudet"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Nykyiset käyttöoikeudet"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Valmistellaan sovellusta…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Tuntematon"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Turvallisuussyistä tabletti ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Turvallisuussyistä televisiosi ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Turvallisuussyistä puhelin ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Tuntemattomat sovellukset voivat helpommin kaapata puhelimesi ja henkilötietosi. Lataamalla sovelluksia tästä lähteestä hyväksyt, että olet itse vastuussa puhelimellesi aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tuntemattomat sovellukset voivat helpommin kaapata tablettisi ja henkilötietosi. Lataamalla sovelluksia tästä lähteestä hyväksyt, että olet itse vastuussa tabletillesi aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tuntemattomat sovellukset voivat helpommin kaapata televisiosi ja henkilötietosi. Lataamalla sovelluksen hyväksyt, että olet itse vastuussa mahdollisista televisiolle aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Jatka"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Asetukset"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear-sovellusten asennus/poistaminen"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fr-rCA-television/strings.xml b/packages/PackageInstaller/res/values-fr-rCA-television/strings.xml
new file mode 100644
index 0000000..f9b360e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fr-rCA-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Refuser et ne plus demander"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Vous pourrez modifier ce choix plus tard dans le menu Paramètres > Applications"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Afficher les applications système"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Autorisations de l\'application"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Autorisations de l\'application"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Autorisations pour <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Autorisations supplémentaires"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Autorisations pour <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fr-rCA-watch/strings.xml b/packages/PackageInstaller/res/values-fr-rCA-watch/strings.xml
new file mode 100644
index 0000000..ad86d016
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fr-rCA-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Refuser et ne plus demander"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Afficher les applications système"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Inchangeable"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Oui"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Annuler"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..e44e465
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Programme installation trousse"</string>
+ <string name="next" msgid="3057143178373252333">"Suivante"</string>
+ <string name="install" msgid="5896438203900042068">"Installer"</string>
+ <string name="done" msgid="3889387558374211719">"Terminé"</string>
+ <string name="cancel" msgid="8360346460165114585">"Annuler"</string>
+ <string name="installing" msgid="8613631001631998372">"Installation..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Application installée."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Voulez-vous installer cette application? Elle pourra :"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Voulez-vous installer cette application? Elle n\'exige aucun accès particulier."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Voulez-vous installer une mise à jour pour cette application? Vos données existantes seront conservées. L\'application mise à jour aura accès à :"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Voulez-vous installer une mise à jour pour cette application intégrée? Vos données existantes seront conservées. L\'application mise à jour aura accès à :"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Voulez-vous installer une mise à jour pour cette application? Vos données ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Voulez-vous installer une mise à jour pour cette application intégrée? Vos données existantes ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Application non installée."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"L\'installation du paquet a été bloquée."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Cette application n\'est pas compatible avec votre téléviseur."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"L\'application n\'a pas été installée, car elle ne semble pas être valide."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur cette tablette."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'a pas pu être installée sur votre téléviseur."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur ce téléphone."</string>
+ <string name="launch" msgid="4826921505917605463">"Ouvrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Cet utilisateur ne peut pas installer les applications inconnues"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gérer les applications"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Espace insuffisant"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Application non trouvée"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"L\'application ne figure pas dans la liste des applications installées."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non autorisé"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erreur"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"L\'application n\'a pas pu être désinstallée."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Désinstaller l\'application"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Désinstaller mise à jour"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Voulez-vous désinstaller cette application?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Désinstallations en cours"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Désinstallations échouées"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Désinstallation..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Désinstallation terminée."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"L\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a bien été désinstallée"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Échec de la désinstallation."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"La désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> n\'a pas réussi."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Cette application est nécessaire pour certains utilisateurs ou profils, et elle a été désinstallée pour d\'autres."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Cette application est nécessaire pour votre profil et ne peut pas être désinstallée."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Impossible de désinstaller l\'application : requise par administrateur appareil."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gérer les applications d\'administration d\'appareils"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gérer les utilisateurs"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Impossible de désinstaller <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Un problème est survenu lors de l\'analyse du paquet."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nouvelles"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Toutes"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Confidentialité"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Accès à l\'appareil"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Cette mise à jour n\'exige pas de nouvelles autorisations."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuser"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"En savoir plus"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Refuser quand même"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Toujours autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Seulement durant l\'utilisation de l\'application"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Toujours"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Refuser et ne plus demander"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> autorisation(s) désactivée(s)"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"toutes les autorisations sont désactivées"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"aucune autorisation n\'est désactivée"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Autoriser"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Applications"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Autorisations applis"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ne plus demander"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Aucune autorisation"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Autorisations supplémentaires"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ouvrir l\'information sur l\'application"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> autre</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> autres</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Cette application a été conçue pour une version antérieure d\'Android. Si vous n\'accordez pas l\'autorisation, il se peut qu\'elle ne fonctionne plus correctement."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"effectuer une action inconnue"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> application(s) autorisée(s) sur <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Afficher le système"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Masquer le système"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Aucune application"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Paramètres de localisation"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> est un fournisseur de services de localisation pour cet appareil. L\'accès à la position peut être modifié dans le menu des paramètres de localisation."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Si vous refusez cette autorisation, il est possible que cela touche certaines fonctionnalités de base de votre appareil."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Activé conformément à la politique"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"L\'accès en arrière-plan est désactivé par la politique"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"L\'accès en arrière-plan est activé par la politique"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"L\'accès en avant-plan est activé par la politique"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Contrôlé par l\'administrateur"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Toujours"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Seulement durant l\'util. de l\'appli"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Jamais"</string>
+ <string name="loading" msgid="7811651799620593731">"Chargement en cours…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Toutes les autorisations"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Autres autorisations de l\'application"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Demande d\'autorisation"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"La superposition d\'écran a été détectée"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Pour modifier ce paramètre d\'autorisation, vous devez tout d\'abord désactiver la superposition d\'écran en accédant à Paramètres > Applications."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Ouvrir les paramètres"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Les actions d\'installation et de désinstallation ne sont pas prises en charge par Android Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Définissez les autorisations d\'accès de l\'application « <xliff:g id="APP_NAME">%1$s</xliff:g> »"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"L\'application « <xliff:g id="APP_NAME">%1$s</xliff:g> » a été mise à jour. Définissez ses autorisations d\'accès."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Annuler"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuer"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nouvelles autorisations"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Autorisations actuelles"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Pré-production de l\'application en cours…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Inconnue"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Votre téléviseur et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuer"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Paramètres"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installer/désinstaller applis Google Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fr-television/strings.xml b/packages/PackageInstaller/res/values-fr-television/strings.xml
new file mode 100644
index 0000000..fa16b94
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fr-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Refuser et ne plus demander"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Vous pourrez modifier ce paramètre plus tard sous Paramètres > Applications."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Afficher les applications système"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Autorisations de l\'application"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Autorisations de l\'application"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Autorisations pour <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Autorisations supplémentaires"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Autorisations pour <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fr-watch/strings.xml b/packages/PackageInstaller/res/values-fr-watch/strings.xml
new file mode 100644
index 0000000..a172e1c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fr-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Refuser et ne plus demander"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Afficher les applications système"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Non modifiable"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Oui"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Annuler"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
new file mode 100644
index 0000000..58d9123
--- /dev/null
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Programme d\'installation du kit"</string>
+ <string name="next" msgid="3057143178373252333">"Suivant"</string>
+ <string name="install" msgid="5896438203900042068">"Installer"</string>
+ <string name="done" msgid="3889387558374211719">"OK"</string>
+ <string name="cancel" msgid="8360346460165114585">"Annuler"</string>
+ <string name="installing" msgid="8613631001631998372">"Installation..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Application installée."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Voulez-vous installer cette application ? Elle permet les actions suivantes :"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Voulez-vous installer cette application ? Elle n\'exige aucun accès particulier."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Voulez-vous installer une mise à jour pour cette application ? Vos données existantes seront conservées. L\'application mise à jour pourra :"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Voulez-vous installer une mise à jour pour cette application intégrée ? Vos données existantes seront conservées. L\'application mise à jour pourra :"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Voulez-vous installer une mise à jour pour cette application ? Vos données ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Voulez-vous installer une mise à jour pour cette application intégrée ? Vos données existantes ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Application non installée."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"L\'installation du package a été bloquée."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"L\'application n\'a pas été installée, car le package entre en conflit avec un package existant."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Cette application n\'est pas compatible avec votre téléviseur."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"L\'application n\'a pas été installée, car le package semble ne pas être valide."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur cette tablette."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre téléviseur."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur ce téléphone."</string>
+ <string name="launch" msgid="4826921505917605463">"Ouvrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gérer les applications"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Mémoire insuffisante"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Application non trouvée"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"L\'application ne figure pas dans la liste des applications installées."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non autorisé"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erreur"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Impossible de désinstaller l\'application."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Désinstaller l\'application"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Désinstaller la mise à jour"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Voulez-vous désinstaller cette application ?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs ? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g> ?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées. Tous les utilisateurs de cet appareil seront affectés, y compris ceux qui ont un profil professionnel."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Désinstallations en cours"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Désinstallations non abouties"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Désinstallation..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Désinstallation de l\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Désinstallation terminée."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"L\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a été désinstallée"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Échec de la désinstallation."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Échec de la désinstallation de l\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Cette application nécessaire pour certains utilisateurs ou profils a été désinstallée pour d\'autres."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Impossible de désinstaller l\'application, car elle est nécessaire pour votre profil."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Impossible désinstaller appli, car elle est requise par administrateur appareil."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gérer les applis d\'administration de l\'appareil"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gérer les utilisateurs"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Impossible de désinstaller <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Un problème est survenu lors de l\'analyse du package."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nouveautés"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Toutes"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Confidentialité"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Accès à l\'appareil"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Cette mise à jour n\'exige pas de nouvelles autorisations."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuser"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Plus d\'infos"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Refuser quand même"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> sur <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Autoriser l\'application <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à <xliff:g id="ACTION">%2$s</xliff:g> ?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Toujours autoriser <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> à <xliff:g id="ACTION">%2$s</xliff:g> ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Seulement lors de l\'utilisation de l\'application"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Toujours"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Refuser et ne plus demander"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> désactivées"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"toutes désactivées"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"aucune désactivée"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Autoriser"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Applications"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Autorisations applis"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ne plus demander"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Aucune autorisation"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Autorisations supplémentaires"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ouvrir les informations sur l\'application"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> autre</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> autres</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Cette application a été conçue pour une ancienne version d\'Android. Si vous désactivez les autorisations, l\'application risque de ne plus fonctionner comme prévu."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"effectuer une action inconnue"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> application(s) autorisée(s) sur <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Afficher les processus système"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Masquer les processus système"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Aucune application"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Paramètres de géolocalisation"</string>
+ <string name="location_warning" msgid="8778701356292735971">"Les services de localisation pour cet appareil sont fournis via <xliff:g id="APP_NAME">%1$s</xliff:g>. Vous pouvez modifier l\'accès aux données de localisation dans les paramètres de localisation."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Si vous refusez cette autorisation, il est possible que cela affecte certaines fonctionnalités de base de votre appareil."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Activé conformément aux règles"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Accès en arrière-plan désactivé conformément au règlement"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Accès en arrière-plan activé conformément au règlement"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Accès au premier plan activé conformément au règlement"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Contrôlé par l\'administrateur"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Toujours"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Seulement lors utilisation appli"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Jamais"</string>
+ <string name="loading" msgid="7811651799620593731">"Chargement en cours…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Toutes les autorisations"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Autres autorisations de l\'application"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Demande d\'autorisation"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Superposition d\'écran détectée"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Pour modifier ce paramètre d\'autorisation, vous devez tout d\'abord désactiver la superposition d\'écran en accédant à Paramètres > Applications."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Ouvrir les paramètres"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Opérations d\'installation et de désinstallation impossibles sur Android Wear"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Sélectionner les éléments auxquels <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> peut accéder"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"L\'application <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> a été mise à jour. Sélectionnez les éléments auxquels elle peut accéder."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Annuler"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuer"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nouvelles autorisations"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Autorisations actuelles"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Pré-production de l\'application…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Inconnu"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Votre téléphone et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de son utilisation."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Votre tablette et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de son utilisation."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Votre téléviseur et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuer"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Paramètres"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installer/Désinstaller les applis Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-gl-television/strings.xml b/packages/PackageInstaller/res/values-gl-television/strings.xml
new file mode 100644
index 0000000..01e8498
--- /dev/null
+++ b/packages/PackageInstaller/res/values-gl-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Denegar e non volver preguntar"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Podes cambiar esta opción máis tarde en Configuración e aplicacións"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostrar aplicacións do sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Permisos de aplicacións"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Permisos de aplicacións"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Permisos de <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Permisos adicionais"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Permisos de <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-gl-watch/strings.xml b/packages/PackageInstaller/res/values-gl-watch/strings.xml
new file mode 100644
index 0000000..5cbb970
--- /dev/null
+++ b/packages/PackageInstaller/res/values-gl-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Denegar, non volver preguntar"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostrar aplicacións do sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Cambio imposible"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Si"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancelar"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
new file mode 100644
index 0000000..f7bf98d
--- /dev/null
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Instalador de paquetes"</string>
+ <string name="next" msgid="3057143178373252333">"Seguinte"</string>
+ <string name="install" msgid="5896438203900042068">"Instalar"</string>
+ <string name="done" msgid="3889387558374211719">"Feito"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalando…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplicación instalada"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Queres instalar esta aplicación? Poderá acceder a:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Queres instalar esta aplicación? Non require ningún acceso especial."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Queres instalar unha actualización para esta aplicación? Non se perderán os teus datos existentes. A aplicación actualizada disporá de acceso a:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Queres instalar unha actualización para esta aplicación integrada? Non se perderán os teus datos existentes. A aplicación actualizada disporá de acceso a:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Queres instalar unha actualización para esta aplicación? Non se perderán os teus datos existentes. Non require ningún acceso especial."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Queres instalar unha actualización para esta aplicación integrada? Non se perderán os teus datos existentes. Non require ningún acceso especial."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplicación non instalada"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Bloqueouse a instalación do paquete."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"A aplicación non se instalou porque o paquete presenta un conflito cun paquete existente."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"A aplicación non se instalou porque a aplicación non é compatible coa tableta."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta aplicación non é compatible coa túa televisión."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"A aplicación non se instalou porque a aplicación non é compatible co teléfono."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"A aplicación non se instalou porque parece que o paquete non é válido."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Non se puido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> na túa tableta."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> non se puido instalar na túa televisión."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Non se puido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> no teu teléfono."</string>
+ <string name="launch" msgid="4826921505917605463">"Abrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"O teu administrador non permite a instalación de aplicacións obtidas a partir de fontes descoñecidas"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este usuario non pode instalar aplicacións descoñecidas"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuario non ten permiso para instalar aplicacións"</string>
+ <string name="ok" msgid="3468756155452870475">"Aceptar"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Xestionar aplicacións"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Espazo esgotado"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Non se puido instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espazo e téntao de novo."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Non se encontrou a aplicación"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Non se atopou a aplicación na lista de aplicacións instaladas."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non permitido"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O usuario actual non pode realizar esta desinstalación."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Non se puido desinstalar a aplicación."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar aplicación"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar actualización"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma parte da seguinte aplicación:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Queres desinstalar esta aplicación?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Queres desinstalar esta aplicación para "<b>"todos"</b>" os usuarios? A aplicación e os seus datos eliminaranse de "<b>"todos"</b>" os usuarios do dispositivo."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Queres desinstalar esta aplicación para o usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos. Isto afectará a todos os usuarios do dispositivo, incluídos os que teñan perfís de traballo."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desintalacións en curso"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Erros nas desinstalacións"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Desinstalando…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstalación finalizada"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Desinstalouse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Desinstalación incorrecta"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"A desinstalación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> non se realizou correctamente."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Non se puido desinstalar a aplicación de administración de dispositivos activa"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Non se puido desinstalar a aplicación de administración de dispositivos activa para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"A aplicación é necesaria para algúns usuarios ou perfís e estaba desinstalada para outros"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"O teu perfil necesita esta aplicación e non se pode desinstalar."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"O administrador do teu dispositivo necesita esta aplicación e non se pode desinstalar."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Xestionar apps de administración de dispositivos"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Administrar usuarios"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Non se puido desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Produciuse un problema ao analizar o paquete."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Todos"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Acceso dispositivo"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Esta actualización non require novos permisos."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Denegar"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Máis información"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denegar igualmente"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Queres permitir á aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Permitir sempre á aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Só ao usar a aplicación"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denegar e non volver preguntar"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desactivados"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"todos desactivados"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ningún desactivado"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicacións"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permisos de aplicacións"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Non preguntar de novo"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Sen permisos"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Permisos adicionais"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir información da aplicación"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> permisos máis</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> permiso máis</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicación deseñouse para unha versión anterior de Android. Denegar o permiso pode provocar que non funcione como está previsto."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"realiza unha acción descoñecida"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicacións con permiso"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Ningunha aplicación"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Configuración da localización"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> é un fornecedor de servizos de localización para este dispositivo. O acceso de localización pode modificarse desde a configuración de localización."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Se denegas este permiso, é posible que as funcións básicas do teu dispositivo deixen de funcionar segundo o previsto."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicado pola política"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"O acceso en segundo plano está desactivado pola política"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"O acceso en segundo plano está activado pola política"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"O acceso en primeiro plano está activado pola política"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Opción controlada polo administrador"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Só ao usar a aplicación"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
+ <string name="loading" msgid="7811651799620593731">"Cargando…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Todos os permisos"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Outras funcionalidades da aplicación"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Solicitude de permiso"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Detectouse unha superposición na pantalla"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Para cambiar a configuración deste permiso, primeiro tes que desactivar a superposición na pantalla, en Configuración > Aplicacións"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configuración"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As accións de instalar e desinstalar non son compatibles con Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Seleccionar os permisos de acceso que queres dar a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Actualizouse a aplicación <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Selecciona os permisos de acceso que lle queres dar."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Novos permisos"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuais"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Probando aplicación…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Descoñecida"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Por cuestións de seguranza, na tableta non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Por cuestións de seguranza, na televisión non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Por cuestións de seguranza, no teléfono non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"O teléfono e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados no teléfono ou da perda dos datos que se poidan derivar do seu uso."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"A tableta e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados na tableta ou da perda dos datos que se poidan derivar do seu uso."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"A televisión e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados na televisión ou da perda dos datos que se poidan derivar do seu uso."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Configuración"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-gu-television/strings.xml b/packages/PackageInstaller/res/values-gu-television/strings.xml
new file mode 100644
index 0000000..b0a40b6
--- /dev/null
+++ b/packages/PackageInstaller/res/values-gu-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"નકારો અને ફરીથી પૂછશો નહીં"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"તમે પછીથી આને સેટિંગ્સ > એપ્લિકેશન્સમાં બદલી શકો છો"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"સિસ્ટમ ઍપ્લિકેશનો બતાવો"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ઍપ્લિકેશન પરવાનગીઓ"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ઍપ્લિકેશન પરવાનગીઓ"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> પરવાનગીઓ"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"વધારાની પરવાનગીઓ"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> પરવાનગીઓ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-gu-watch/strings.xml b/packages/PackageInstaller/res/values-gu-watch/strings.xml
new file mode 100644
index 0000000..6e83cf2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-gu-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"નકારો, ફરીથી પૂછશો નહીં"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"સિસ્ટમ ઍપ્લિકેશનો બતાવો"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"બદલી શકતાં નથી"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"હા"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"રદ કરો"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml
new file mode 100644
index 0000000..5e0a2b3
--- /dev/null
+++ b/packages/PackageInstaller/res/values-gu/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"પૅકેજ ઇન્સ્ટોલર"</string>
+ <string name="next" msgid="3057143178373252333">"આગલું"</string>
+ <string name="install" msgid="5896438203900042068">"ઇન્સ્ટોલ કરો"</string>
+ <string name="done" msgid="3889387558374211719">"થઈ ગયું"</string>
+ <string name="cancel" msgid="8360346460165114585">"રદ કરો"</string>
+ <string name="installing" msgid="8613631001631998372">"ઇન્સ્ટોલ કરી રહ્યું છે…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને ઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ઍપ્લિકેશન ઇન્સ્ટોલ કરી."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"શું તમે આ ઍપ્લિકેશન ઇન્સ્ટોલ કરવા માંગો છો? તે આની ઍક્સેસ મેળવશે:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"શું તમે આ એપ્લિકેશનને ઇન્સ્ટોલ કરવા માંગો છો? તેને કોઈપણ વિશિષ્ટ ઍક્સેસની જરૂર નથી."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"શું તમે આ અસ્તિત્વમાંની એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. અપડેટ કરેલ એપ્લિકેશનને આની ઍક્સેસ મળશે:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"શું તમે આ બિલ્ટ-ઇન એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. અપડેટ કરેલ એપ્લિકેશનને આની ઍક્સેસ મળશે:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"શું તમે આ અસ્તિત્વમાંની એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. તેને કોઈ વિશિષ્ટ ઍક્સેસની જરૂર હોતી નથી."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"શું તમે આ બિલ્ટ-ઇન એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. તેને કોઈ વિશિષ્ટ ઍક્સેસની જરૂર હોતી નથી."</string>
+ <string name="install_failed" msgid="6579998651498970899">"ઍપ્લિકેશન ઇન્સ્ટોલ કરેલ નથી."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"પૅકેજને ઇન્સ્ટૉલ થવાથી અવરોધિત કરવામાં આવ્યું હતું."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"પૅકેજનો અસ્તિત્વમાંના પૅકેજ સાથે વિરોધાભાસ હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"તમારા ટેબ્લેટ સાથે ઍપ્લિકેશન સુસંગત ન હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"આ અૅપ્લિકેશન તમારા ટીવી સાથે સુસંગત નથી."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"તમારા ફોન સાથે ઍપ્લિકેશન સુસંગત ન હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"પૅકેજ અમાન્ય લાગી રહ્યું હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"તમારા ટેબ્લેટ પર <xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાયું નથી."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"તમારા ટીવી પર <xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાયું નથી."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"તમારા ફોન પર <xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાયું નથી."</string>
+ <string name="launch" msgid="4826921505917605463">"ખોલો"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"તમારા વ્યવસ્થાપક અજાણ્યા સ્રોતોથી મેળવેલ ઍપ્લિકેશનોના ઇન્સ્ટૉલેશનની મંજૂરી આપતા નથી"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"આ વપરાશકર્તા અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરી શકશે નહીં"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"આ વપરાશકર્તાને ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી"</string>
+ <string name="ok" msgid="3468756155452870475">"ઓકે"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"એપ્લિકેશન્સનું સંચાલન કરો"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"જગ્યાની બહાર"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાઈ નથી. થોડી સ્પેસ ખાલી કરો અને ફરીથી પ્રયાસ કરો."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ઍપ્લિકેશન મળી નથી"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ઇન્સ્ટોલ કરેલ ઍપ્લિકેશન્સની સૂચિમાં ઍપ્લિકેશન મળી નહોતી."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"મંજૂરી નથી"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"વર્તમાન વપરાશકર્તાને આ અનઇન્સ્ટૉલેશન કરવાની મંજૂરી નથી."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ભૂલ"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ઍપ્લિકેશન અનઇન્સ્ટૉલ કરી શકાઈ નહીં."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ઍપ્લિકેશન અનઇન્સ્ટોલ કરો"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"અપડેટ અનઇન્સ્ટોલ કરો"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> એ નીચેની એપ્લિકેશનનો એક ભાગ છે:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"શું તમે આ એપ્લિકેશનને અનઇન્સ્ટોલ કરવા માંગો છો?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"શું તમે "<b>"તમામ"</b>" વપરાશકર્તાઓ માટે આ ઍપ્લિકેશનને અનઇન્સ્ટોલ કરવા માગો છો? ઉપકરણ પરના "<b>"તમામ"</b>" વપરાશકર્તાઓમાંથી ઍપ્લિકેશન અને તેનો ડેટા દૂર કરવામાં આવશે."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"શું તમે <xliff:g id="USERNAME">%1$s</xliff:g> વપરાશકર્તા માટે આ એપ્લિકેશનને અનઇન્સ્ટોલ કરવા માગો છો?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"આ ઍપ્લિકેશનને ફેક્ટરી સંસ્કરણથી બદલીએ? તમામ ડેટા દૂર કરવામાં આવશે."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"આ ઍપ્લિકેશનને ફેક્ટરી સંસ્કરણથી બદલીએ? તમામ ડેટા દૂર કરવામાં આવશે. આનાથી કાર્ય પ્રોફાઇલ્સ સાથેના વપરાશકર્તાઓ સહિત આ ઉપકરણના તમામ વપરાશકર્તાઓ પ્રભાવિત થશે."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ચાલી રહેલા અનઇન્સ્ટૉલ"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"નિષ્ફળ થયેલા અનઇન્સ્ટૉલ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"અનઇન્સ્ટોલ કરી રહ્યું છે..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ને અનઇન્સ્ટૉલ કરી રહ્યાં છે…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"અનઇન્સ્ટોલ કરો સમાપ્ત થયું."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> અનઇન્સ્ટૉલ કર્યું"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"અનઇન્સ્ટોલ કરવું અસફળ રહ્યું."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ને અનઇન્સ્ટૉલ કરવું અસફળ રહ્યું."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"સક્રિય ઉપકરણ વ્યવસ્થાપક ઍપ્લિકેશનોને અનઇન્સ્ટૉલ કરી શકાતી નથી"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> માટે સક્રિય ઉપકરણ વ્યવસ્થાપક ઍપ્લિકેશનોને અનઇન્સ્ટૉલ કરી શકાતી નથી"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"આ અૅપ્લિકેશન અમુક વપરાશકર્તાઓ અથવા પ્રોફાઇલ્સ માટે જરૂરી છે અને તે અન્ય લોકો માટે અનઇન્સ્ટૉલ કરી હતી"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"તમારી કાર્યાલયની પ્રોફાઇલ માટે ઍપ્લિકેશન જરૂરી છે અને અનઇન્સ્ટૉલ કરી શકાતી નથી."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"આ ઍપ્લિકેશન તમારા ઉપકરણ વ્યવસ્થાપક માટે આવશ્યક છે અને તે અનઇન્સ્ટોલ કરી શકાતી નથી."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ઉપકરણ વ્યવસ્થાપક ઍપ્લિકેશનોનું સંચાલન કરો"</string>
+ <string name="manage_users" msgid="3125018886835668847">"વપરાશકર્તાઓનું સંચાલન કરો"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> અનઇન્સ્ટોલ કરી શકાઈ નથી."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"પૅકેજનું વિશ્લેષણ કરવામાં એક સમસ્યા આવી હતી."</string>
+ <string name="newPerms" msgid="6039428254474104210">"નવું"</string>
+ <string name="allPerms" msgid="1024385515840703981">"તમામ"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ગોપનીયતા"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ઉપકરણ ઍક્સેસ"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"આ અપડેટને કોઈ નવી પરવાનગીઓની જરૂર નથી."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"નકારો"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"વધુ માહિતી"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"કોઇપણ રીતે નકારો"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> માંથી <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ને <xliff:g id="ACTION">%2$s</xliff:g> મંજૂરી આપીએ?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ને હંમેશા <xliff:g id="ACTION">%2$s</xliff:g>ની મંજૂરી આપીએ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"માત્ર ઍપનો ઉપયોગ કરતી વખતે જ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"હંમેશા"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"નકારો અને ફરીથી પૂછશો નહીં"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> અક્ષમ કરી"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"તમામ અક્ષમ કરી"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"કોઈપણ અક્ષમ કરેલ નથી"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"મંજૂરી આપો"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ઍપ્લિકેશનો"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ઍપ્લિકેશન પરવાનગીઓ"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ફરીથી પૂછશો નહીં"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"કોઈ પરવાનગીઓ નથી"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"વધારાની પરવાનગીઓ"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ઍપ માહિતી ખોલો"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> વધુ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> વધુ</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"આ ઍપ્લિકેશન Android ના જુના સંસ્કરણ માટે તૈયાર કરવામાં આવી હતી. પરવાનગી નકારવાથી તે ધાર્યા પ્રમાણે બિલકુલ કાર્ય કરશે નહી."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"એક અજાણી ક્રિયા કરો"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> માંથી <xliff:g id="COUNT_0">%1$d</xliff:g> એપ્લિકેશન્સને મંજૂરી છે"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"સિસ્ટમ બતાવો"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"સિસ્ટમ છુપાવો"</string>
+ <string name="no_apps" msgid="1965493419005012569">"કોઇ ઍપ્લિકેશનો નથી"</string>
+ <string name="location_settings" msgid="1774875730854491297">"સ્થાન સેટિંગ્સ"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> એ આ ઉપકરણ માટે સ્થાન સેવાઓના પ્રદાતા છે. સ્થાન સેટિંગ્સમાંથી સ્થાન ઍક્સેસ સંશોધિત કરી શકાય છે."</string>
+ <string name="system_warning" msgid="7103819124542305179">"જો તમે આ પરવાનગી નકારો છો, તો તમારા ઉપકરણની મૂળભૂત સુવિધાઓ અપેક્ષા પ્રમાણે કાર્ય કરી શકશે નહીં."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"નીતિ દ્વારા લાગુ"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"નીતિ દ્વારા બૅકગ્રાઉન્ડ ઍક્સેસને બંધ કરવામાં આવ્યો છે"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"નીતિ દ્વારા બૅકગ્રાઉન્ડ ઍક્સેસને ચાલુ કરવામાં આવ્યો છે"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"નીતિ દ્વારા ફૉરગ્રાઉન્ડ ઍક્સેસને ચાલુ કરવામાં આવ્યો છે"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"હંમેશા"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"માત્ર ઍપનો ઉપયોગ કરતી વખતે જ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ક્યારેય નહીં"</string>
+ <string name="loading" msgid="7811651799620593731">"લોડ કરી રહ્યું છે..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"બધી પરવાનગીઓ"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"અન્ય ઍપ્લિકેશન ક્ષમતાઓ"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"પરવાનગીની વિનંતી"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"સ્ક્રીન ઓવરલે મળ્યું"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"આ પરવાનગી સેટિંગ બદલવા માટે, તમારે પહેલા સેટિંગ્સ > Apps માંથી સ્ક્રીન ઓવરલે બંધ કરવું પડશે"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"સેટિંગ્સ ખોલો"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear પર ઇન્સ્ટૉલ/અનઇન્સ્ટૉલ ક્રિયાઓ સમર્થિત નથી."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ને શેના ઍક્સેસ માટેની મંજૂરી આપવી તે પસંદ કરો"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> અપડેટ કરવામાં આવી છે. આ ઍપ્લિકેશનને શેના ઍક્સેસ માટેની મંજૂરી આપવી તે પસંદ કરો."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"રદ કરો"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ચાલુ રાખો"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"નવી પરવાનગીઓ"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"વર્તમાન પરવાનગીઓ"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ઍપ્લિકેશન અમલમં છે..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"અજાણી"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"તમારી સુરક્ષા માટે, તમારા ટૅબ્લેટને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"તમારી સુરક્ષા માટે, તમારા ટીવીને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"તમારી સુરક્ષા માટે, તમારા ફોનને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"તમારો ફોન અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ફોનને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"તમારું ટૅબ્લેટ અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ટૅબ્લેટને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"તમારું ટીવી અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ટીવીને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ચાલુ રાખો"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"સેટિંગ્સ"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"એમ્બેડ ઍપ્લિકેશનો ઇન્સ્ટૉલ/અનઇન્સ્ટૉલ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hi-television/strings.xml b/packages/PackageInstaller/res/values-hi-television/strings.xml
new file mode 100644
index 0000000..2acd9c5
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hi-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"मना करें और फिर से ना पूछें"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"आप इसे बाद में सेटिंग > ऐप्स में बदल सकते हैं"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"सिस्टम ऐप्स दिखाएं"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ऐप्लिकेशन अनुमतियां"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ऐप्लिकेशन अनुमतियां"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> अनुमतियां"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"और अनुमतियां"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> अनुमतियां"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hi-watch/strings.xml b/packages/PackageInstaller/res/values-hi-watch/strings.xml
new file mode 100644
index 0000000..f7adb0c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hi-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"मना करें, फिर से ना पूछें"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"सिस्टम ऐप्स दिखाएं"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"बदला नहीं जा सकता"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"हां"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"रद्द करें"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
new file mode 100644
index 0000000..5ddddbe
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"पैकेज इंस्टॉलर"</string>
+ <string name="next" msgid="3057143178373252333">"आगे"</string>
+ <string name="install" msgid="5896438203900042068">"इंस्टॉल करें"</string>
+ <string name="done" msgid="3889387558374211719">"हो गया"</string>
+ <string name="cancel" msgid="8360346460165114585">"रद्द करें"</string>
+ <string name="installing" msgid="8613631001631998372">"इंस्टॉल कर रहा है…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इंस्टॉल हो रहा है…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ऐप्स इंस्टॉल हो गया."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"क्या आप इस ऐप्स को इंस्टॉल करना चाहते हैं? इससे यहां पर पहुंच प्राप्त होगी:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"क्या आप इस ऐप्स को इंस्टॉल करना चाहते हैं? इसके लिए किसी विशेष पहुंच की आवश्यकता नहीं है."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"क्या आप इस मौजूदा ऐप के बारे में नई जानकारी इंस्टॉल करना चाहते हैं? आपका मौजूदा डेटा गुम नहीं होगा. अपडेट किये गए ऐप से आपको इन पर पहुंच मिलेगी:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"क्या आप इस बिल्ट-इन ऐप के बारे में नई जानकारी इंस्टॉल करना चाहते हैं? आपका मौजूदा डेटा गुम नहीं होगा. नई जानकारी वाले ऐप से आपको इन पर मिलेगी:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"क्या आप इस मौजूदा ऐप में नई जानकारी इंस्टॉल करना चाहते हैं? आपका मौजूदा डेटा बना रहेगा. इसे किसी खास पहुंच की ज़रुरत नहीं होती."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"क्या आप इस मौजूदा ऐप में नई जानकारी इंस्टॉल करना चाहते हैं? आपका मौजूदा डेटा बना रहेगा. इसे किसी खास पहुंच की ज़रुरत नहीं होती."</string>
+ <string name="install_failed" msgid="6579998651498970899">"ऐप्स इंस्टॉल नहीं हुआ."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"पैकेज को इंस्टॉल होने से अवरुद्ध किया हुआ है."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज का किसी मौजूदा पैकेज से विरोध है."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि ऐप्लिकेशन आपके टैबलेट से संगत नहीं है."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"यह ऐप आपके टीवी के संगत नहीं है."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि ऐप्लिकेशन आपके फ़ोन से संगत नहीं है."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज अमान्य लग रहा है."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> को आपके टैबलेट पर इंस्टॉल नहीं किया जा सका."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> को आपके टीवी पर इंस्टॉल नहीं किया जा सकता."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> को आपके फ़ोन पर इंस्टॉल नहीं किया जा सका."</string>
+ <string name="launch" msgid="4826921505917605463">"खोलें"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"आपका व्यवस्थापक अनजान स्रोतों से मिलने वाले ऐप्लिकेशन को इंस्टॉल करने की अनुमति नहीं देता है"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"यह उपयोगकर्ता अनजान ऐप्लिकेशन इंस्टॉल नहीं कर सकता"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"इस उपयोगकर्ता ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है"</string>
+ <string name="ok" msgid="3468756155452870475">"ठीक है"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"ऐप्स प्रबंधित करें"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"जगह नहीं है"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> को इंस्टॉल नहीं किया जा सका. थोड़ी जगह खाली करें और फिर से कोशिश करें."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ऐप्स नहीं मिला"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ऐप्स , इंस्टॉल किए गए ऐप्स की सूची में नहीं मिला था."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"अनुमति नहीं है"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"मौजूदा उपयोगकर्ता को यह अनइंस्टॉल करने की अनुमति नहीं है"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"गड़बड़ी"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ऐप्लिकेशन अनइंस्टॉल नहीं किया जा सका."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ऐप्स अनइंस्टॉल करें"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"अपडेट अनइंस्टॉल करें"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्न ऐप्स का भाग है:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"क्या आप इस ऐप्स को अनइंस्टॉल करना चाहते हैं?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"क्या आप इस ऐप्स को "<b>"सभी"</b>" उपयोगकर्ताओं के लिए अनइंस्टॉल करना चाहते हैं? ऐप्स और उसके डेटा को डिवाइस पर "<b>"सभी"</b>" उपयोगकर्ताओं से निकाल दिया जाएगा."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"क्या आप उपयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> के लिए इस ऐप को अनइंस्टॉल करना चाहते हैं?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"इस ऐप्लिकेशन को फ़ैक्टरी वर्शन से बदलें? सभी डेटा निकाल दिया जाएगा."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"इस ऐप्लिकेशन को फ़ैक्ट्री वर्शन से बदलें? पूरा डेटा निकाल दिया जाएगा. इसका इस डिवाइस के सभी उपयोगकर्ताओं पर असर पड़ेगा, जिनमें कार्य प्रोफ़ाइल वाले उपयोगकर्ता शामिल हैं."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"वे अनइंस्टॉल जो चल रहे हैं"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"वे अनइंस्टॉल जो सफल नहीं रहे"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"अनइंस्टॉल कर रहा है…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया जा रहा है…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"अनइंस्टॉल करना पूर्ण हो गया."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया गया"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"अनइंस्टॉल करना विफल."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को अनइंस्टॉल करना असफल."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"सक्रिय डिवाइस व्यवस्थापक ऐप्लिकेशन को अनइंस्टॉल नहीं किया जा सकता"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> के लिए सक्रिय डिवाइस व्यवस्थापक ऐप्लिकेशन को अनइंस्टॉल नहीं किया जा सकता"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"यह ऐप्लिकेशन कुछ उपयोगकर्ताओं या प्रोफ़ाइल हेतु आवश्यक है और अन्य हेतु अनइंस्टॉल हो गया है"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"आपकी कार्य प्रोफ़ाइल के लिए यह ऐप्लिकेशन आवश्यक है और उसे अनइंस्टॉल नहीं किया जा सकता."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"आपके डिवाइस व्यवस्थापक के लिए यह ऐप्स जरूरी है व इसे अनइंस्टॉल नहीं किया जा सकता."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"डिवाइस व्यवस्थापक ऐप्लिकेशन प्रबंधित करें"</string>
+ <string name="manage_users" msgid="3125018886835668847">"उपयोगकर्ताओं को प्रबंधित करें"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> को अनइंस्टॉल नहीं किया जा सका."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"पैकेज को पार्स करने में कोई समस्या थी."</string>
+ <string name="newPerms" msgid="6039428254474104210">"नया"</string>
+ <string name="allPerms" msgid="1024385515840703981">"सभी"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"निजता"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"डिवाइस पहुंच"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"इस अपडेट लिए अनुमति की ज़रुरत नहीं है."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"अस्वीकार करें"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"अधिक जानकारी"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"फिर भी अस्वीकार करें"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> में से <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को <xliff:g id="ACTION">%2$s</xliff:g> की अनुमति दें?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को हमेशा <xliff:g id="ACTION">%2$s</xliff:g> की अनुमति दें?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"सिर्फ़ ऐप्लिकेशन इस्तेमाल करते समय"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"हमेशा"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"अनुमति न दें और दोबारा न पूछें"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> अक्षम"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"सभी अक्षम हैं"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"कोई भी अक्षम नहीं है"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"अनुमति दें"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ऐप्लिकेशन"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ऐप्लिकेशन अनुमतियां"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"फिर से न पूछें"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"कोई अनुमति नहीं"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"और अनुमतियां"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ऐप्लिकेशन से जुड़ी जानकारी देखें"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> और</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> और</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"इस ऐप को Android के पुराने वर्शन के लिए डिज़ाइन किया गया था. अनुमति अस्वीकार करने पर हो सकता है कि फ़ंक्शन लक्षित रूप से काम नहीं करे."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"कोई अज्ञात कार्रवाई करें"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> में से <xliff:g id="COUNT_0">%1$d</xliff:g> ऐप्लिकेशन को अनुमति है"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"सिस्टम दिखाएं"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"सिस्टम छिपाएं"</string>
+ <string name="no_apps" msgid="1965493419005012569">"कोई ऐप्स नहीं"</string>
+ <string name="location_settings" msgid="1774875730854491297">"जगह की सेटिंग"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> इस डिवाइस के लिए जगह की जानकारी उपलब्ध कराता है. जगह की पहुंच (एक्सेस) को जगह की सेटिंग से बदला जा सकता है."</string>
+ <string name="system_warning" msgid="7103819124542305179">"यदि आप इस अनुमति को अस्वीकार करते हैं, तो हो सकता है कि आपके डिवाइस की मूलभूत सुविधाएं लक्षित कार्य ना कर पाएं."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"नीति द्वारा लागू"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"नीति के मुताबिक बैकग्राउंड एक्सेस बंद किया गया"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"नीति के मुताबिक बैकग्राउंड एक्सेस चालू किया गया"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"नीति के मुताबिक फ़ोरग्राउंड एक्सेस चालू किया गया"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"इसका नियंत्रण एडमिन के पास है"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"हमेशा"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ऐप्लिकेशन इस्तेमाल करते समय"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"कभी नहीं"</string>
+ <string name="loading" msgid="7811651799620593731">"लोड हो रहा है…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"सभी अनुमतियां"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"अन्य ऐप कार्यक्षमताएं"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"अनुमति का अनुरोध"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"स्क्रीन ओवरले मिला"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"इस अनुमति सेटिंग को बदलने के लिए, आपको पहले सेटिंग > ऐप, से स्क्रीन ओवरले को बंद करना होगा"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"सेटिंग खोलें"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"इंस्टॉल/अनइंस्टॉल किए जाने की कार्रवाइयां Wear पर समर्थित नहीं हैं."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"यह चुनें कि <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को किस-किस चीज पर पहुंचने देना चाहते हैं"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> को अपडेट कर दिया गया है. यह चुनें कि इस ऐप्लिकेशन को किस-किस चीज तक पहुंचने देना चाहते हैं."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"रद्द करें"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"जारी रखें"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"नई अनुमतियां"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"वर्तमान अनुमतियां"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ऐप्लिकेशन चरणबद्ध किया जा रहा है…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"अज्ञात"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"आपकी सुरक्षा के लिए, आपके टैबलेट को इस स्रोत से आने वाले अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"आपकी सुरक्षा के लिए, आपके टीवी को इस स्रोत से आने वाले अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"आपकी सुरक्षा के लिए, आपके फ़ोन को इस स्रोत से आने वाले अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"आपका फ़ोन और व्यक्तिगत डेटा अज्ञात ऐप्लिकेशन के हमले के प्रति अधिक संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके आप सहमति देते हैं कि इसके उपयोग के चलते आपके फ़ोन को होने वाले किसी भी नुकसान या डेटा की हानि के लिए आप ज़िम्मेदार हैं."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"आपका टैबलेट और व्यक्तिगत डेटा अज्ञात ऐप्लिकेशन के हमले के प्रति अधिक संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके आप सहमति देते हैं कि इसके उपयोग के चलते आपके टैबलेट को होने वाले किसी भी नुकसान या डेटा की हानि के लिए आप ज़िम्मेदार हैं."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"आपका टीवी और व्यक्तिगत डेटा अज्ञात ऐप्लिकेशन के हमले के प्रति अधिक संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके आप सहमति देते हैं कि इसके उपयोग के चलते आपके टीवी को होने वाले किसी भी नुकसान या डेटा की हानि के लिए आप ज़िम्मेदार हैं."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"जारी रखें"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"सेटिंग"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"वियर ऐप इंस्टॉल/अनइंस्टॉल हो रहे हैं"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hr-television/strings.xml b/packages/PackageInstaller/res/values-hr-television/strings.xml
new file mode 100644
index 0000000..ba363f4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hr-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Odbij i više ne pitaj"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"To možete kasnije promijenili u odjeljku Postavke > Aplikacije"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Prikaži aplikacije sustava"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Dopuštenja aplikacije"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Dopuštenja aplikacije"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Dopuštenja – <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Dodatna dopuštenja"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Dopuštenja – <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hr-watch/strings.xml b/packages/PackageInstaller/res/values-hr-watch/strings.xml
new file mode 100644
index 0000000..cd44eee
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hr-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Ne, više ne pitaj"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Prikaži aplikacije sustava"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Promjena nemoguća"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Da"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Odustani"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
new file mode 100644
index 0000000..3884ae5
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Alat za instaliranje paketa"</string>
+ <string name="next" msgid="3057143178373252333">"Sljedeća"</string>
+ <string name="install" msgid="5896438203900042068">"Instaliraj"</string>
+ <string name="done" msgid="3889387558374211719">"Gotovo"</string>
+ <string name="cancel" msgid="8360346460165114585">"Odustani"</string>
+ <string name="installing" msgid="8613631001631998372">"Instaliranje..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikacija je instalirana."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Želite li instalirati ovu aplikaciju? Aplikacija će moći sljedeće:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Želite li instalirati ovu aplikaciju? Aplikacija ne zahtijeva nikakav poseban pristup."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Želite li instalirati ažuriranje postojeće aplikacije? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija dobit će pristup sljedećem:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Želite li instalirati ažuriranje za ovu ugrađenu aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija dobit će pristup sljedećem:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Želite li instalirati ažuriranje postojeće aplikacije? Vaši postojeći podaci neće se izgubiti. Nije potreban nikakav poseban pristup."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Želite li instalirati ažuriranje te ugrađene aplikacije? Vaši postojeći podaci neće se izgubiti. Nije potreban nikakav poseban pristup."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikacija nije instalirana."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Instaliranje paketa blokirano je."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija koja nije instalirana kao paket u sukobu je s postojećim paketom."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija koja nije instalirana kao aplikacija nije kompatibilna s vašim tabletom."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikacija nije kompatibilna s vašim televizorom."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija koja nije instalirana kao aplikacija nije kompatibilna s vašim telefonom."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija koja nije instalirana kao paket vjerojatno nije važeća."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati na ovo tabletno računalo."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nije bilo moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na vaš televizor."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati na vaš telefon."</string>
+ <string name="launch" msgid="4826921505917605463">"Otvori"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Vaš administrator ne dopušta instaliranje aplikacija iz nepoznatih izvora"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ovaj korisnik ne može instalirati nepoznate aplikacije"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ovaj korisnik nema dopuštenje za instaliranje aplikacija"</string>
+ <string name="ok" msgid="3468756155452870475">"U redu"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Upravljanje aplikacijama"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nema dovoljno mjesta"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati. Oslobodite dio prostora i pokušajte ponovo."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacija nije pronađena"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Na popisu instaliranih aplikacija ova aplikacija nije pronađena."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nije dopušteno"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Trenutačni korisnik nema dopuštenje za to deinstaliranje."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Pogreška"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Deinstaliranje aplikacije nije uspjelo."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Deinstaliraj aplikaciju"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Deinstalacija ažuriranja"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"Aktivnost <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> dio je sljedeće aplikacije:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Želite li deinstalirati ovu aplikaciju?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Želite li deinstalirati tu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i njezini podaci bit će uklonjeni sa "<b>"svih"</b>" korisnika na uređaju."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Želite li deinstalirati tu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke. To se odnosi na sve korisnike uređaja, uključujući one s radnim profilima."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Deinstaliranja u tijeku"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspjela deinstaliranja"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Deinstaliranje..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Deinstalacija je završena."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalirana"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Deinstalacija nije uspjela."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspjelo."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Deinstaliranje aktivne aplikacije administratora uređaja nije uspjelo"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nije uspjelo deinstaliranje aktivne aplikacije administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ta je aplikacija obavezna za neke korisnike ili profile, deinstalirana je za ostale"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ta je aplikacija potrebna za vaš profil i ne može se deinstalirati."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ta je aplikacija neophodna administratoru uređaja i nije ju moguće deinstalirati."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Upravljaj aplikacijama administratora uređaja"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Upravljaj korisnicima"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Došlo je do problema pri analiziranju paketa."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Sve"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privatnost"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Pristup uređaja"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Ovo ažuriranje ne zahtijeva nove dozvole."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odbij"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Više informacija"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Svejedno odbij"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Želite li aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dopustiti da može <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Želite li uvijek dopustiti aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> sljedeće: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo dok se aplikacija koristi"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Uvijek"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odbij i više ne pitaj"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Onemogućeno: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"sve onemogućeno"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ništa nije onemogućeno"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dopusti"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Dopuštenja aplikacije"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Više me ne pitaj"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nema dopuštenja"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Dodatna dopuštenja"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvori informacije o aplikaciji"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ova je aplikacija napravljena za stariju verziju Androida. Ako ne dobije dopuštenje, možda više neće funkcionirati kako treba."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"izvršiti nepoznatu radnju"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Aplikacije s dopuštenjem: <xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Prikaži sustav"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Sakrij sustav"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nema aplikacija"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Postavke lokacije"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> pruža usluge lokacije za ovaj uređaj. Pristup lokaciji može se izmijeniti u postavkama lokacije."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ako ne odobrite ovo dopuštenje, osnovne značajke vašeg uređaja možda više neće funkcionirati pravilno."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Provoditi se na temelju pravila"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Pristup u pozadini onemogućen je pravilima"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Pristup u pozadini omogućen je pravilima"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Pristup u prednjem planu omogućen je pravilima"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolira administrator"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Uvijek"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo dok se aplikacija koristi"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nikad"</string>
+ <string name="loading" msgid="7811651799620593731">"Učitavanje…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Sva dopuštenja"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Ostale mogućnosti aplikacije"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Zahtijevanje dopuštenja"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Otkriveno je preklapanje na zaslonu"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Da biste promijenili tu postavku dopuštenja, prvo morate isključiti preklapanje na zaslonu u Postavkama > Aplikacije"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Otvori postavke"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Radnje instaliranja i deinstaliranja nisu podržane na Wearu."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Odaberite čemu će <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> moći pristupiti"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ažurirana je. Odaberite čemu će moći pristupiti."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Otkaži"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Nastavi"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nova dopuštenja"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Trenutačna dopuštenja"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Postavljanje aplikacije…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Nepoznato"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Iz sigurnosnih razloga tablet nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Iz sigurnosnih razloga televizor nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Iz sigurnosnih razloga telefon nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Vaš telefon i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje telefona ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Vaš tablet i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje tableta ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Vaš TV i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje televizora ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Nastavi"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Postavke"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instaliranje/deinstaliranje Wear apl."</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hu-television/strings.xml b/packages/PackageInstaller/res/values-hu-television/strings.xml
new file mode 100644
index 0000000..0557700
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hu-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Megtagadás, és ne jelenjen meg többé"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Ezt később módosíthatja a Beállítások > Alkalmazások pontnál"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Rendszeralkalmazások megjelenítése"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Alkalmazásengedélyek"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Alkalmazásengedélyek"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> – jogosultságok"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"További engedélyek"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> – jogosultságok"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hu-watch/strings.xml b/packages/PackageInstaller/res/values-hu-watch/strings.xml
new file mode 100644
index 0000000..8ae3504
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hu-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Megtagadás, ne jelenjen meg"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>/<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Rendszeralkalmazások megjelenítése"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Nem változtatható"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Igen"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Mégse"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml
new file mode 100644
index 0000000..5e96550
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hu/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Csomagtelepítő"</string>
+ <string name="next" msgid="3057143178373252333">"Tovább"</string>
+ <string name="install" msgid="5896438203900042068">"Telepítés"</string>
+ <string name="done" msgid="3889387558374211719">"Kész"</string>
+ <string name="cancel" msgid="8360346460165114585">"Mégse"</string>
+ <string name="installing" msgid="8613631001631998372">"Telepítés..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> telepítése…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Alkalmazás telepítve."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Telepíti ezt az alkalmazást? Az a következőkhöz fog hozzáférést kapni:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Telepíti ezt az alkalmazást? Az alkalmazás nem igényel különleges hozzáférést."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Telepít egy frissítést ehhez a meglévő alkalmazáshoz? A meglévő adatai nem vesznek el. A frissített alkalmazás a következőkhöz kap hozzáférést:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Telepít egy frissítést ehhez a beépített alkalmazáshoz? A meglévő adatai nem vesznek el. A frissített alkalmazás a következőkhöz kap hozzáférést:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Telepít egy frissítést ehhez a meglévő alkalmazáshoz? A meglévő adatai nem vesznek el. A frissítés nem igényel különleges hozzáférést."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Telepít egy frissítést ehhez a beépített alkalmazáshoz? A meglévő adatai nem vesznek el. A frissítés nem igényel különleges hozzáférést."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Az alkalmazás nincs telepítve."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"A csomag telepítését letiltotta a rendszer."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"A nem csomagként telepített alkalmazás ütközik egy már létező csomaggal."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"A nem alkalmazásként telepített alkalmazás nem kompatibilis az Ön táblagépével."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ez az alkalmazás nem kompatibilis tévéjével."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"A nem alkalmazásként telepített alkalmazás nem kompatibilis az Ön telefonjával."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"A nem csomagként telepített alkalmazás érvénytelen."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető táblagépére."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető a tévéjére."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető telefonjára."</string>
+ <string name="launch" msgid="4826921505917605463">"Megnyitás"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"A rendszergazda nem engedélyezi az ismeretlen forrásokból származó alkalmazások telepítését"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ez a felhasználó nem telepíthet ismeretlen alkalmazásokat"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ez a felhasználó nem telepíthet alkalmazásokat"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Alkalmazások kezelése"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nincs elég hely"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazást nem lehet telepíteni. Szabadítson fel egy kis helyet, és próbálja újra."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Az alkalmazás nem található"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Az alkalmazás nem található a telepített alkalmazások listájában."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nem engedélyezett"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"A jelenlegi felhasználó számára nem engedélyezett az eltávolítás végrehajtása."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Hiba"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Az alkalmazás nem távolítható el."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Alkalmazás eltávolítása"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Frissítés eltávolítása"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"A(z) <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> a következő alkalmazás része:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Eltávolítja ezt az alkalmazást?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Szeretné eltávolítani ezt az alkalmazást "<b>"minden"</b>" felhasználónál? Az alkalmazást és adatait az eszköz "<b>"minden"</b>" felhasználójánál töröljük."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Eltávolítja ezt az alkalmazást <xliff:g id="USERNAME">%1$s</xliff:g> felhasználó esetében?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik. Ez az eszköz összes felhasználóját érinti, így a munkaprofilokkal rendelkezőket is."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Futó telepítések"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Sikertelen telepítések"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Eltávolítás..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása folyamatban van…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Az eltávolítás befejeződött."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása befejeződött"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Az eltávolítás sikertelen."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása nem sikerült."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nem lehet eltávolítani az aktív eszközrendszergazdai alkalmazást"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nem lehet eltávolítani az aktív eszközrendszergazdai alkalmazást <xliff:g id="USERNAME">%1$s</xliff:g> felhasználó esetében"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Egyes felhasználóknak/profiloknak szüksége van erre, másoknál pedig eltávolították"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ez az alkalmazás szükséges a profiljához, így nem távolítható el."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Az alkalmazásra szüksége van az eszköz adminisztrátorának, és nem távolítható el."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Eszközrendszergazdai alkalmazások kezelése"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Felhasználók kezelése"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nem sikerült a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> eltávolítása"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Gond volt a csomag elemzésekor."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Új"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Mind"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Adatvédelem"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Eszközhozzáférés"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"A frissítés nem igényel új engedélyeket."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Elutasítás"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"További információ"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tiltás mindenképpen"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>/<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> számára a következőt: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Mindig engedélyezi a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b&gt számára a következőt: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Az alkalmazás használatakor"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Mindig"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Megtagadás, és ne jelenjen meg többé"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> van letiltva"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"az összes le van tiltva"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"egy sincs letiltva"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Engedélyezés"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Alkalmazások"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Alkalmazásengedélyek"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ne jelenjen meg többé"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nincs engedély"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"További engedélyek"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Alkalmazásinformációk megnyitása"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> további</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> további</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ez az alkalmazás az Android egy korábbi verziójához készült. Az engedély megtagadása esetén előfordulhat, hogy a továbbiakban nem fog megfelelően működni."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"végrehajt egy ismeretlen műveletet"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>/<xliff:g id="COUNT_0">%1$d</xliff:g> alkalmazás engedélyezve"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Rendszerfolyamatok megjelenítése"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Rendszerfolyamatok elrejtése"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nincsenek alkalmazások"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Helybeállítások"</string>
+ <string name="location_warning" msgid="8778701356292735971">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> helyszolgáltatásokat biztosít ennek az eszköznek. A helyhozzáférést a helybeállításokban lehet módosítani."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ha ezt nem engedélyezi, akkor előfordulhat, hogy az eszköz egyes alapfunkciói nem megfelelően fognak működni."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Irányelv által kényszerítve"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Háttérhozzáférés házirend által letiltva"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Háttérhozzáférés házirend által engedélyezve"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Előtérbeli hozzáférés házirend által engedélyezve"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Rendszergazda által irányítva"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Mindig"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Az alkalmazás használatakor"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Soha"</string>
+ <string name="loading" msgid="7811651799620593731">"Betöltés…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Az összes engedély"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Egyéb alkalmazáslehetőségek"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Engedélykérés"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Képernyőfedvény észlelve"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Ennek az engedélynek a módosításához először ki kell kapcsolnia a képernyőfedvényt a Beállítások > Alkalmazások menüben"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Beállítások megnyitása"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"A Wear nem támogatja a telepítés/eltávolítás műveletet."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Válassza ki, hogy a(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> mihez férjen hozzá"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"A(z) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> frissítése megtörtént. Válassza ki, hogy mihez férjen hozzá ez az alkalmazás."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Mégse"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Tovább"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Új engedélyek"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Jelenlegi engedélyek"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Alkalmazás fokozatos közzététele…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Ismeretlen"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Az Ön biztonsága érdekében táblagépe nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Az Ön biztonsága érdekében tévéje nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Az Ön biztonsága érdekében telefonja nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonja és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elismeri, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a telefont ért károkért."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Táblagépe és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elismeri, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a táblagépet ért károkért."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tévéje és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elismeri, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a tévét ért károkért."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Tovább"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Beállítások"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear-alkalmazások telepítése/törlése"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hy-television/strings.xml b/packages/PackageInstaller/res/values-hy-television/strings.xml
new file mode 100644
index 0000000..f260673
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hy-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Մերժել և այլևս չհարցնել"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Կարող եք փոխել սա ավելի ուշ Կարգավորումներում և Հավելվածներում"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Ցուցադրել համակարգի հավելվածները"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Հավելվածի թույլտվությունները"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Հավելվածի թույլտվությունները"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> թույլտվությունները"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Լրացուցիչ թույլտվություններ"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> թույլտվությունները"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hy-watch/strings.xml b/packages/PackageInstaller/res/values-hy-watch/strings.xml
new file mode 100644
index 0000000..5538858
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hy-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Մերժել, այլևս չհարցնել"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Ցուցադրել համակարգի հավելվածները"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Հնարավոր չէ փոխել"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Այո"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Չեղարկել"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
new file mode 100644
index 0000000..e89f1ec
--- /dev/null
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Փաթեթի տեղադրիչ"</string>
+ <string name="next" msgid="3057143178373252333">"Հաջորդը"</string>
+ <string name="install" msgid="5896438203900042068">"Տեղադրել"</string>
+ <string name="done" msgid="3889387558374211719">"Պատրաստ է"</string>
+ <string name="cancel" msgid="8360346460165114585">"Չեղարկել"</string>
+ <string name="installing" msgid="8613631001631998372">"Տեղադրվում է..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի տեղադրում…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Հավելվածը տեղադրված է:"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Ցանկանու՞մ եք տեղադրել այս ծրագիրը: Այն մուտքի հնարավորություն կունենա`"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ցանկանու՞մ եք տեղադրել այս հավելվածը: Այն հատուկ մուտք չի պահանջում:"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Ցանկանու՞մ եք այս առկա հավելվածում թարմացում տեղադրել: Ձեր ընթացիկ տվյալները չեն կորի: Նորացված հավելվածը կստանա մատչում`"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ցանկանու՞մ եք այս ներկառուցված հավելվածում թարմացում տեղադրել: Ձեր առկա տվյալները չեն կորի: Նորացված հավելվածը կստանա մատչում `"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ցանկանու՞մ եք այս առկա հավելվածում թարմացում տեղադրել: Ձեր ընթացիկ տվյալները չեն կորի: Այն չի պահանջում որևէ հատուկ մուտք:"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ցանկանու՞մ եք այս ներկառուցված հավելվածում թարմացում տեղադրել: Ձեր ընթացիկ տվյալները չեն կորի: Այն չի պահանջում որևէ հատուկ մուտք:"</string>
+ <string name="install_failed" msgid="6579998651498970899">"Հավելվածը տեղադրված չէ:"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Փաթեթի տեղադրումն արգելափակվել է:"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթն ունի հակասություն առկա փաթեթի հետ:"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Հավելվածը չի տեղադրվել, քանի որ այն համատեղելի չէ ձեր պլանշետի հետ:"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Այս հավելվածը համատեղելի չէ ձեր հեռուստացույցի հետ:"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Հավելվածը չի տեղադրվել, քանի որ այն համատեղելի չէ ձեր հեռախոսի հետ:"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթը, կարծես թե, վնասված է:"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց տեղադրել ձեր պլանշետում:"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Չհաջողվեց տեղադրել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր հեռուստացույցի վրա:"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց տեղադրել ձեր հեռախոսում:"</string>
+ <string name="launch" msgid="4826921505917605463">"Բացել"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ձեր ադմինիստրատորը թույլ չի տալիս տեղադրել հավելվածներ անհայտ աղբյուրներից"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Այս օգտատերը չի կարող անհայտ հավելվածներ տեղադրել"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Այս օգտատիրոջը չի թույլատրվում տեղադրել հավելվածներ"</string>
+ <string name="ok" msgid="3468756155452870475">"Հաստատել"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Կառավարել հավելվածները"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Տարածքից դուրս"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց տեղադրել: Ազատեք որոշակի տարածք և կրկին փորձեք:"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Հավելվածը չի գտնվել"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Հավելվածը չի գտնվել տեղադրված հավելվածների ցանկում:"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Արգելված է"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Ընթացիկ օգտատերը հեռացնելու թույլտվություն չունի:"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Սխալ"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Հնարավոր չէ հեռացնել հավելվածը:"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Ապատեղադրել հավելվածը"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Ապատեղադրել թարմացումը"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>-ը հետևյալ հավելվածի մասն է`"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Ուզո՞ւմ եք ապատեղադրել այս հավելվածը։"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ցանկանու՞մ եք ապատեղադրել այս հավելվածը "<b>"բոլոր"</b>" օգտատերերի համար: Հավելվածը և դրա տվյալները կհեռացվեն սարքի "<b>"բոլոր"</b>" օգտատերերից:"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ցանկանում եք ապատեղադրե՞լ այս ծրագիրը <xliff:g id="USERNAME">%1$s</xliff:g> օգտատիրոջ համար:"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն:"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն: Դա վերաբերում է այս սարքի բոլոր օգտատերերին, այդ թվում նաև աշխատանքային պրոֆիլներ ունեցողներին:"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Ընթացիկ հեռացումներ"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ձախողված հեռացումներ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Ապատեղադրում է..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը հեռացվում է…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Ապատեղադրումը ավարտված է:"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Հեռացված <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Ապատեղադրումն անհաջող է:"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Չհաջողվեց հեռացնել <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը:"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Հնարավոր չէ հեռացնել ակտիվ սարքի ադմինիստրատորի հավելվածը"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Հնարավոր չէ հեռացնել ակտիվ սարքի ադմինիստրատորի հավելվածը <xliff:g id="USERNAME">%1$s</xliff:g> օգտատիրոջ համար"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Այս հավելվածն անհրաժեշտ է որոշ օգտատերերի կամ պրոֆիլների համար և մնացածի մոտ հեռացվել է"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Այս հավելվածն անհրաժեշտ է ձեր պրոֆիլի համար: Այն հնարավոր չէ հեռացնել:"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ծրագիրը ձեր սարքի ադմինիստրատորի կողմից նշվել է որպես պարտադիր և չի կարող հեռացվել:"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Կառավարել սարքի ադմինիստրատորի հավելվածները"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Կառավարել օգտատերերին"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց ապատեղադրել:"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Փաթեթը վերլուծելիս խնդիր առաջացավ:"</string>
+ <string name="newPerms" msgid="6039428254474104210">"Նոր"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Բոլորը"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Գաղտնիություն"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Սարքի մատչում"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Այս թարմացումը պահանջում է, որ նոր թույլտվություններ չտրվեն:"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Մերժել"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Այլ տեղեկություններ"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Մերժել ամեն դեպքում"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>-ը <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-ից"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Թույլատրե՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին <xliff:g id="ACTION">%2$s</xliff:g>:"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Միշտ թույլ տա՞լ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին <xliff:g id="ACTION">%2$s</xliff:g>:"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Միայն հավելվածն օգտագործելիս"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Միշտ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Մերժել և այլևս չհարցնել"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"կասեցվել է <xliff:g id="COUNT">%1$d</xliff:g> թույլտվություն"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"բոլոր թույլտվությունները կասեցվել են"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ոչ մի թույլտվություն չի կասեցվել"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Թույլատրել"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Հավելվածներ"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Հավելվածների թույլտվություններ"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Այլևս չհարցնել"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Թույլտվություններ չկան"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Լրացուցիչ թույլտվություններ"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Հավելվածի մասին"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Եվս <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Եվս <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Այս հավելվածը նախատեսված է Android-ի ավելի հին տարբերակի համար: Եթե մերժեք թույլտվությունը, այն կարող է չաշխատել ինչպես հարկն է:"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"թույլատրել անհայտ գործողություն"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Թույլատրված է <xliff:g id="COUNT_0">%1$d</xliff:g> հավելվածի՝ <xliff:g id="COUNT_1">%2$d</xliff:g>-ից"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Ցուցադրել համակարգայինները"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Թաքցնել համակարգայինները"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Հավելվածներ չկան"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Տեղորոշման կարգավորումներ"</string>
+ <string name="location_warning" msgid="8778701356292735971">"Այս սարքի տեղորոշման ծառայությունները տրամադրում է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը: Տեղադրության ցուցադրման կարգավորումները կարող եք փոխել տեղադրության կարգավորումներից:"</string>
+ <string name="system_warning" msgid="7103819124542305179">"Եթե չտրամադրեք այս թույլտվությունը, ձեր սարքի հիմնական գործառույթները հնարավոր է սխալ աշխատեն:"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Սահմանված է կանոններով"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Հասանելիությունը ֆոնային ռեժիմում անջատած է կանոնի համաձայն"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Հասանելիությունը ֆոնային ռեժիմում միացված է կանոնի համաձայն"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Հասանելիությունն ակտիվ ռեժիմում միացված է կանոնի համաձայն"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Միշտ"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Միայն հավելվածն օգտագործելիս"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Երբեք"</string>
+ <string name="loading" msgid="7811651799620593731">"Բեռնում…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Բոլոր թույլտվությունները"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Այլ հավելվածների հնարավորությունները"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Թույլտվության հարցում"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Ցուցադրում այլ պատուհանների վրա"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Այս թույլտվության կարգավորումները փոխելու համար նախ անհրաժեշտ է անջատել էկրանի վերադրումը՝ անցնելով Կարգավորումներ > Հավելվածներ"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Բացել կարգավորումները"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Տեղադրման/հեռացման գործողությունները Android Wear-ում չեն աջակցվում:"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Ընտրեք, ինչ թույլտվություններ եք ցանկանում տրամադրել <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածին"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> հավելվածը թարմացվել է: Ընտրեք, ինչ թույլտվություններ եք ցանկանում տրամադրել այդ հավելվածին:"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Չեղարկել"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Շարունակել"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Նոր թույլտվությունները"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Առկա թույլտվությունները"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Հավելվածի նախապատրաստում…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Անհայտ"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Անվտանգության նկատառումներից ելնելով՝ ձեր պլանշետին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Անվտանգության նկատառումներից ելնելով՝ ձեր հեռուստացույցին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Անվտանգության նկատառումներից ելնելով՝ ձեր հեռախոսին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ձեր հեռախոսը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր հեռախոսին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ձեր պլանշետը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր պլանշետին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ձեր TV-ն և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր TV-ին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Շարունակել"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Կարգավորումներ"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear հավելվածների տեղադրում/հեռացում"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-in-television/strings.xml b/packages/PackageInstaller/res/values-in-television/strings.xml
new file mode 100644
index 0000000..8e6e9ab
--- /dev/null
+++ b/packages/PackageInstaller/res/values-in-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Tolak dan jangan tanya lagi"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Anda dapat mengubah ini nanti di Setelan > Aplikasi"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Tampilkan aplikasi sistem"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Izin aplikasi"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Izin aplikasi"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Izin <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Izin tambahan"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Izin <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-in-watch/strings.xml b/packages/PackageInstaller/res/values-in-watch/strings.xml
new file mode 100644
index 0000000..ca2e087
--- /dev/null
+++ b/packages/PackageInstaller/res/values-in-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Tolak, jangan tanya lagi"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Tampilkan aplikasi sistem"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Tidak dapat diubah"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ya"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Batal"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml
new file mode 100644
index 0000000..afae29a
--- /dev/null
+++ b/packages/PackageInstaller/res/values-in/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pemasang paket"</string>
+ <string name="next" msgid="3057143178373252333">"Berikutnya"</string>
+ <string name="install" msgid="5896438203900042068">"Instal"</string>
+ <string name="done" msgid="3889387558374211719">"Selesai"</string>
+ <string name="cancel" msgid="8360346460165114585">"Batal"</string>
+ <string name="installing" msgid="8613631001631998372">"Memasang..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Menginstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Apl terpasang."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Apakah Anda ingin memasang aplikasi ini? Aplikasi akan memiliki akses ke:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Apakah Anda ingin memasang aplikasi ini? Aplikasi tidak memerlukan akses khusus apa pun."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Apakah Anda ingin memasang pembaruan ke aplikasi yang ada? Data Anda yang ada tidak akan hilang. Aplikasi yang diperbarui akan mendapatkan akses ke:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Apakah Anda ingin memasang pembaruan ke aplikasi yang tertanam? Data Anda yang ada tidak akan hilang. Aplikasi yang diperbarui akan mendapatkan akses ke:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Anda ingin memasang pembaruan ke aplikasi yang ada ini? Data Anda yang ada akan hilang. Tindakan ini tidak memerlukan akses khusus apa pun."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Anda ingin memasang pembaruan ke aplikasi yang ada di dalamnya? Data Anda yang ada akan hilang. Tindakan ini tidak memerlukan akses khusus apa pun."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Apl tidak terpasang."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paket diblokir sehingga tidak dapat dipasang."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikasi yang tidak dipasang sebagai paket akan bentrok dengan paket yang sudah ada."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikasi yang tidak dipasang sebagai aplikasi tidak kompatibel dengan tablet Anda."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikasi ini tidak kompatibel dengan TV Anda."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikasi yang tidak dipasang sebagai aplikasi tidak kompatibel dengan ponsel Anda."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikasi yang tidak dipasang sebagai paket tampaknya tidak valid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang pada tablet Anda."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang di TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang pada ponsel Anda."</string>
+ <string name="launch" msgid="4826921505917605463">"Buka"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Admin tidak mengizinkan penginstalan aplikasi yang didapatkan dari sumber tidak dikenal"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aplikasi yang tidak dikenal tidak dapat diinstal oleh pengguna ini"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Pengguna ini tidak diizinkan menginstal aplikasi"</string>
+ <string name="ok" msgid="3468756155452870475">"Oke"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Kelola apl"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Kehabisan ruang penyimpanan"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang. Kosongkan sebagian ruang dan coba lagi."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Apl tidak ditemukan"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Apl tersebut tidak ditemukan di dalam daftar apl yang terpasang."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Tidak diizinkan"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Pengguna saat ini tidak diizinkan meng-uninstal."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Kesalahan"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikasi tidak dapat dipasang."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstal apl"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstal pembaruan"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> adalah bagian dari apl berikut:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Apakah Anda ingin meng-uninstal apl ini?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Anda ingin mencopot aplikasi ini untuk "<b>"semua"</b>" pengguna? Aplikasi dan datanya akan dihapus dari "<b>"semua"</b>" pengguna pada perangkat."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ingin meng-uninstal aplikasi ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Gantikan aplikasi ini dengan versi pabrik? Semua data akan dihapus."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Gantikan aplikasi ini dengan versi pabrik? Semua data akan dihapus. Tindakan ini memengaruhi semua pengguna perangkat ini, termasuk yang memiliki profil kerja."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Menjalankan uninstal"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Uninstal yang gagal"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Mencopot pemasangan..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Mencopot pemasangan <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Pencopotan pemasangan selesai."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> di-uninstal"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Pencopotan pemasangan tidak berhasil."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Gagal meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Tidak dapat meng-uninstal aplikasi admin perangkat yang aktif"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Tidak dapat meng-uninstal aplikasi admin perangkat yang aktif untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplikasi ini diperlukan untuk beberapa pengguna atau profil, dan telah dicopot pemasangannya untuk yang lainnya"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Aplikasi ini diperlukan untuk profil Anda dan tidak dapat dicopot pemasangannya."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Aplikasi diwajibkan administrator perangkat & pemasangannya tidak bisa dicopot."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Kelola aplikasi admin perangkat"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Kelola pengguna"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dicopot pemasangannya."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Terjadi masalah saat mengurai paket."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Baru"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Semua"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privasi"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Akses Perangkat"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Pembaruan ini tidak memerlukan izin baru."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Tolak"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Info selengkapnya"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tetap tolak"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> dari <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Izinkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> untuk <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Selalu izinkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> untuk <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Hanya saat menggunakan aplikasi"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Selalu"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Tolak dan jangan tanya lagi"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> dinonaktifkan"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"semua dinonaktifkan"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"tidak ada yang dinonaktifkan"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Izinkan"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikasi"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Izin aplikasi"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Jangan tanya lagi"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Tidak ada izin"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Izin tambahan"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Buka info aplikasi"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> lainnya</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> lainnya</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Aplikasi ini dirancang untuk versi lama Android. Menolak izin dapat menyebabkan aplikasi tidak berfungsi lagi sesuai harapan."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"melakukan tindakan yang tidak dikenal"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> dari <xliff:g id="COUNT_1">%2$d</xliff:g> aplikasi diizinkan"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Tampilkan sistem"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Sembunyikan sistem"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Tidak ada aplikasi"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Setelan Lokasi"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah penyedia layanan lokasi untuk perangkat ini. Akses lokasi dapat diubah dari setelan lokasi."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Jika Anda menolak izin ini, fitur dasar perangkat mungkin tidak berfungsi lagi sesuai harapan."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Diterapkan menurut kebijakan"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Akses background dinonaktifkan oleh kebijakan"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Akses background diaktifkan oleh kebijakan"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Akses latar depan diaktifkan oleh kebijakan"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Dikontrol oleh admin"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Selalu"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Hanya saat menggunakan aplikasi"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Tidak pernah"</string>
+ <string name="loading" msgid="7811651799620593731">"Memuat…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Semua izin"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Kemampuan aplikasi lainnya"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Permintaan izin"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Hamparan layar terdeteksi"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Untuk mengubah setelan izin ini, terlebih dahulu Anda harus menonaktifkan hamparan layar dari Setelan > Aplikasi"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Buka setelan"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instal/Uninstal tidak didukung di Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Pilih item yang boleh diakses oleh <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> telah diperbarui. Pilih item yang boleh diakses oleh aplikasi ini."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Batal"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Lanjutkan"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Izin baru"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Izin saat ini"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Menyiapkan aplikasi..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Tidak dikenal"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Demi keamanan, TV tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Demi keamanan, TV tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Demi keamanan, ponsel tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Data pribadi dan ponsel lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan ponsel atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Data pribadi dan tablet lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan tablet atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Data pribadi dan TV lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan TV atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Lanjutkan"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Setelan"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Melakukan instal/uninstal aplikasi Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-is-television/strings.xml b/packages/PackageInstaller/res/values-is-television/strings.xml
new file mode 100644
index 0000000..0c1fad7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-is-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Hafna og ekki spyrja aftur"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Þú getur breytt þessu seinna undir Stillingar og forrit"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Sýna kerfisforrit"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Heimildir forrita"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Heimildir forrita"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Heimildir fyrir <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Viðbótarheimildir"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Heimildir fyrir <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-is-watch/strings.xml b/packages/PackageInstaller/res/values-is-watch/strings.xml
new file mode 100644
index 0000000..b82da5e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-is-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Hafna, ekki spyrja aftur"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Sýna kerfisforrit"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Má ekki breyta"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Já"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Hætta við"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml
new file mode 100644
index 0000000..ea0bdcb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-is/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Uppsetningarforrit pakka"</string>
+ <string name="next" msgid="3057143178373252333">"Áfram"</string>
+ <string name="install" msgid="5896438203900042068">"Setja upp"</string>
+ <string name="done" msgid="3889387558374211719">"Lokið"</string>
+ <string name="cancel" msgid="8360346460165114585">"Hætta við"</string>
+ <string name="installing" msgid="8613631001631998372">"Setur upp…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Setur upp <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Forritið er uppsett."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Viltu setja þetta forrit upp? Það mun fá aðgang að:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Viltu setja þetta forrit upp? Það krefst ekki neins sérstaks aðgangs."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Viltu setja upp uppfærslu á þessu uppsetta forriti? Eldri gögn glatast ekki. Uppfærða forritið mun fá aðgang að:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Viltu setja upp uppfærslu á þessu innbyggða forriti? Eldri gögn glatast ekki. Uppfærða forritið mun fá aðgang að:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Viltu setja upp uppfærslu á þessu uppsetta forriti? Eldri gögn glatast ekki. Forritið krefst ekki neins sérstaks aðgangs."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Viltu setja upp uppfærslu á þessu innbyggða forriti? Eldri gögn glatast ekki. Forritið krefst ekki neins sérstaks aðgangs."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Forritið er ekki uppsett."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Lokað var á uppsetningu pakkans."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Forritið var ekki sett upp vegna árekstra á milli pakkans og annars pakka."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Forritið var ekki sett upp því að forritið er ekki samhæft við spjaldtölvuna þína."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Þetta forrit er ekki samhæft við sjónvarpið."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Forritið var ekki sett upp því að forritið er ekki samhæft við símann þinn."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Forritið var ekki sett upp því að pakkinn virðist vera ógildur."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í spjaldtölvunni."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Ekki var hægt að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í sjónvarpinu."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í símanum."</string>
+ <string name="launch" msgid="4826921505917605463">"Opna"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Kerfisstjórinn leyfir ekki uppsetningu forrita af óþekktum uppruna"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Þessi notandi getur ekki sett upp óþekkt forrit"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Þessi notandi hefur ekki leyfi til að setja upp forrit"</string>
+ <string name="ok" msgid="3468756155452870475">"Í lagi"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Stjórna forritum"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Ekkert pláss eftir"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Ekki tókst að setja upp <xliff:g id="APP_NAME">%1$s</xliff:g>. Losaðu um pláss og reyndu aftur."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Forritið finnst ekki"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Forritið fannst ekki á listanum yfir uppsett forrit."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ekki heimilað"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Núverandi notandi hefur ekki heimild til að fjarlægja þetta."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Villa"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Ekki tókst að fjarlægja forritið."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Fjarlægja forrit"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Fjarlægja uppfærslu"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er hluti af þessu forriti:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Viltu fjarlægja þetta forrit?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Viltu fjarlægja þetta forrit hjá "<b>"öllum"</b>" notendum? Forritið og gögn þess verða fjarlægð hjá "<b>"öllum"</b>" notendum tækisins."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Viltu fjarlægja þetta forrit fyrir notandann <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð. Þetta hefur áhrif á alla notendur tækisins, þar á meðal þá sem eru með vinnusnið."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Fjarlægingar í gangi"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Fjarlægingar sem mistókust"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Fjarlægir…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Fjarlægir <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Forritið hefur verið fjarlægt."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Fjarlægði <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Ekki tókst að fjarlægja forritið."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Ekki tókst að fjarlægja <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ekki er hægt að fjarlægja virkt forrit tækjastjóra"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ekki er hægt að fjarlægja virkt forrit tækjastjóra fyrir <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Þessa forrits er krafist hjá sumum notendum eða sniðum en var fjarlægt hjá öðrum"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Sniðið þitt krefst þessa forrits og ekki er hægt að fjarlægja það."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Stjórnandi tækisins krefst þessa forrits og ekki er hægt að fjarlægja það."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Stjórna forritum tækjastjóra"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Stjórna notendum"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Ekki tókst að fjarlægja <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Vandamál kom upp við að vinna úr pakkanum."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nýjar"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Allar"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Persónuvernd"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Tækisaðgangur"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Þessi uppfærsla krefst engra nýrra heimilda."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Hafna"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Frekari upplýsingar"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Hafna samt"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> af <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Leyfa forritinu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> að <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Viltu alltaf veita <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> leyfi til að <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Aðeins þegar forrit er í notkun"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Alltaf"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Hafna og ekki spyrja aftur"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> óvirkar"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"allar óvirkar"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"engin óvirk"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Leyfa"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Forrit"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Heimildir forrits"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ekki spyrja aftur"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Engar heimildir"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Viðbótarheimildir"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Opna upplýsingar um forrit"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> í viðbót</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> í viðbót</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Þetta forrit var hannað fyrir eldri útgáfu af Android. Ef því er ekki veitt heimild er hugsanlegt að það virki ekki rétt."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"framkvæma óþekkta aðgerð"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> forrit af <xliff:g id="COUNT_1">%2$d</xliff:g> leyfð"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Sýna kerfisforrit"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Fela kerfisforrit"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Engin forrit"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Staðsetningarstillingar"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> býður upp á staðsetningarþjónustu fyrir þetta tæki. Hægt er að breyta aðgangi að staðsetningu í stillingum staðsetningar."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ef þú veitir ekki þessa heimild getur verið að grunneiginleikar tækisins virki ekki lengur sem skyldi."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Stjórnað af reglu"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Bakgrunnsaðgangur óvirkur vegna reglu"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Bakgrunnsaðgangur virkur vegna reglu"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Forgrunnsaðgangur virkur vegna reglu"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Stjórnað af kerfisstjóra"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Alltaf"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Aðeins þegar forrit er í notkun"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Aldrei"</string>
+ <string name="loading" msgid="7811651799620593731">"Hleður…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Allar heimildir"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Aðrir forritseiginleikar"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Beiðni um heimild"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Skjáyfirlögn greindist"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Til að breyta þessari heimildarstillingu þarftu fyrst að slökkva á skjáyfirlögn undir Stillingar > Forrit"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Opna stillingar"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Aðgerðir til að setja upp / fjarlægja eru ekki studdar í Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Veldu hverju <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> fær aðgang að"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> hefur verið uppfært. Veldu hverju forritið fær aðgang að."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Hætta við"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Halda áfram"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nýjar heimildir"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Núgildandi heimildir"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Setur upp forrit…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Óþekkt"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Til að tryggja öryggi þitt er ekki heimild í spjaldtölvunni þinni fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Til að tryggja öryggi þitt er ekki heimild í sjónvarpinu þínu fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Til að tryggja öryggi þitt er ekki heimild í símanum þínum fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Síminn þinn og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á símanum eða gagnatapi sem leiða kann af notkun þess."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Spjaldtölvan þín og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á spjaldtölvunni eða gagnatapi sem leiða kann af notkun þess."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Sjónvarpið þitt og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á sjónvarpinu eða gagnatapi sem leiða kann af notkun þess."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Áfram"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Stillingar"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Uppsetning/fjarlæging Wear forrita"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-it-television/strings.xml b/packages/PackageInstaller/res/values-it-television/strings.xml
new file mode 100644
index 0000000..14c46de
--- /dev/null
+++ b/packages/PackageInstaller/res/values-it-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Nega e non chiedermelo più"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Puoi modificare questa scelta in seguito in Impostazioni > App"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostra app di sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Autorizzazioni app"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Autorizzazioni app"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Autorizzazioni <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Altre autorizzazioni"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Autorizzazioni <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-it-watch/strings.xml b/packages/PackageInstaller/res/values-it-watch/strings.xml
new file mode 100644
index 0000000..73b2ab1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-it-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Nega e non chiedermelo più"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostra app di sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Imposs modif"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Sì"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Annulla"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
new file mode 100644
index 0000000..5870722
--- /dev/null
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Installazione pacchetti"</string>
+ <string name="next" msgid="3057143178373252333">"Avanti"</string>
+ <string name="install" msgid="5896438203900042068">"Installa"</string>
+ <string name="done" msgid="3889387558374211719">"Fine"</string>
+ <string name="cancel" msgid="8360346460165114585">"Annulla"</string>
+ <string name="installing" msgid="8613631001631998372">"Installazione..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App installata."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Vuoi installare questa applicazione? Avrà accesso a:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vuoi installare questa applicazione? Non richiede alcun accesso speciale."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Vuoi installare un aggiornamento per questa applicazione esistente? I tuoi dati esistenti non andranno persi. L\'applicazione aggiornata avrà accesso a:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vuoi installare un aggiornamento per questa applicazione integrata? I tuoi dati esistenti non andranno persi. L\'applicazione aggiornata avrà accesso a:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vuoi installare un aggiornamento di questa applicazione esistente? I dati correnti verranno conservati. Non occorrono accessi speciali."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vuoi installare un aggiornamento di questa applicazione integrata? I dati correnti verranno conservati. Non occorrono accessi speciali."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App non installata."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"È stata bloccata l\'installazione del pacchetto."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App non installata poiché il pacchetto è in conflitto con un pacchetto esistente."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App non installata poiché non compatibile con il tuo tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Questa app non è compatibile con la tua TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App non installata poiché non compatibile con il tuo telefono."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App non installata poiché il pacchetto risulta non valido."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sul tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sulla tua TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sul telefono."</string>
+ <string name="launch" msgid="4826921505917605463">"Apri"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"L\'amministratore non consente l\'installazione di app ottenute da fonti sconosciute"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Questo utente non può installare app sconosciute"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"L\'utente non è autorizzato a installare app"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gestisci applicazioni"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Spazio esaurito"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera dello spazio e riprova."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Applicazione non trovata"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Impossibile trovare l\'applicazione nell\'elenco di applicazioni installate."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non autorizzato"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'utente corrente non è autorizzato a eseguire questa disinstallazione."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Errore"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Impossibile disinstallare l\'app."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Disinstalla applicazione"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Disinstalla aggiornamento"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fa parte della seguente applicazione:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Vuoi disinstallare questa applicazione?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vuoi disinstallare questa applicazione per "<b>"tutti"</b>" gli utenti? L\'applicazione e i relativi dati verranno rimossi da "<b>"tutti"</b>" gli utenti configurati sul dispositivo."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Disinstallare l\'app per l\'utente <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi. Saranno interessati tutti gli utenti del dispositivo, inclusi quelli che hanno profili di lavoro."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Disinstallazioni attuali"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Disinstallazioni non riuscite"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Disinstallazione..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Disinstallazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Disinstallazione completata."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"App <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> disinstallata"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Disinstallazione non riuscita."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Impossibile disinstallare <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Impossibile disinstallare l\'app di amministrazione del dispositivo attiva"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Impossibile disinstallare l\'app di amministrazione del dispositivo attiva per <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"L\'app è necessaria per alcuni utenti/profili ed è stata disinstallata per altri"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"L\'app è necessaria per il tuo profilo e non può essere disinstallata."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"App richiesta dall\'amministratore del dispositivo. Non può essere disinstallata."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gestisci app di amministrazione del dispositivo"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gestisci utenti"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Impossibile disinstallare <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Errore durante l\'analisi del pacchetto."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nuove"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Tutte"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Accesso dispositivo"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Questo aggiornamento non richiede nuove autorizzazioni."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Nega"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Altre informazioni"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Nega comunque"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> di <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Consentire a <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vuoi consentire sempre all\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> di <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Solo durante l\'uso dell\'app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Nega e non chiedermelo più"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disattivate"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"tutte disattivate"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nessuna disattivata"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Consenti"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"App"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Autorizzazioni app"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Non chiedermelo più"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nessuna autorizzazione"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Altre autorizzazioni"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Visualizza informazioni sull\'app"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Altre <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> altra</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Questa app è stata sviluppata per una versione precedente di Android. Se l\'autorizzazione viene negata, l\'app potrebbe non funzionare più come previsto."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"esegue un\'azione sconosciuta"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Sono consentite <xliff:g id="COUNT_0">%1$d</xliff:g> app su <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostra app di sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Nascondi app di sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nessuna app"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Geolocalizzazione"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> è un fornitore di servizi di geolocalizzazione per questo dispositivo. È possibile modificare l\'accesso alla posizione dalle impostazioni sulla posizione."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Se neghi questa autorizzazione, le funzionalità di base del dispositivo potrebbero non funzionare più come previsto."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Applicata in base alle norme"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Accesso in background disattivato in base alla norma"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Accesso in background attivato in base alla norma"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Accesso in primo piano attivato in base alla norma"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Gestita dall\'amministratore"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Solo durante l\'uso dell\'app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Mai"</string>
+ <string name="loading" msgid="7811651799620593731">"Caricamento…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Tutte le autorizzazioni"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Altre funzionalità dell\'app"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Richiesta di autorizzazione"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Overlay schermo rilevato"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Per modificare questa impostazione di autorizzazione, devi innanzitutto disattivare l\'overlay schermo da Impostazioni > App"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Apri impostazioni"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Le azioni di installazione/disinstallazione non sono supportate su Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Scegli i dati a cui l\'app <xliff:g id="APP_NAME">%1$s</xliff:g> può accedere"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"L\'app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> è stata aggiornata. Scegli i dati a cui può accedere."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Annulla"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continua"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nuove autorizzazioni"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Autorizzazioni correnti"</string>
+ <string name="message_staging" msgid="6151794817691100003">"App in preparazione…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Sconosciuto"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Per sicurezza, il tuo tablet non è autorizzato a installare app sconosciute da questa origine."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Per sicurezza, la tua TV non è autorizzata a installare app sconosciute da questa origine."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Per sicurezza, il tuo telefono non è autorizzato a installare app sconosciute da questa origine."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"I dati del telefono e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al telefono o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"I dati del tablet e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al tablet o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"I dati della TV e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni alla TV o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continua"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Impostazioni"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installazione/disinstallazione di app Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-iw-television/strings.xml b/packages/PackageInstaller/res/values-iw-television/strings.xml
new file mode 100644
index 0000000..1ec1cd7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-iw-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"דחה ואל תשאל שוב"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ניתן לשנות זאת מאוחר יותר ב\'הגדרות\' > \'אפליקציות\'"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"הצג אפליקציות מערכת"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"הרשאות לאפליקציות"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"הרשאות לאפליקציות"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"הרשאות <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"הרשאות נוספות"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"הרשאות <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-iw-watch/strings.xml b/packages/PackageInstaller/res/values-iw-watch/strings.xml
new file mode 100644
index 0000000..34dd0d3
--- /dev/null
+++ b/packages/PackageInstaller/res/values-iw-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"דחה ואל תשאל שוב"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"הצג אפליקציות מערכת"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"לא ניתן לשנות"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"כן"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"ביטול"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
new file mode 100644
index 0000000..414fe4c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"מתקין החבילה"</string>
+ <string name="next" msgid="3057143178373252333">"הבא"</string>
+ <string name="install" msgid="5896438203900042068">"התקן"</string>
+ <string name="done" msgid="3889387558374211719">"סיום"</string>
+ <string name="cancel" msgid="8360346460165114585">"ביטול"</string>
+ <string name="installing" msgid="8613631001631998372">"מתקין..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"מתקין את <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"האפליקציה הותקנה."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"האם ברצונך להתקין את האפליקציה? היא תקבל גישה אל:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"האם ברצונך להתקין את האפליקציה? היא אינה דורשת גישה מיוחדת."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"האם ברצונך להתקין עדכון לאפליקציה קיימת זו? הנתונים הקיימים שלך לא יאבדו. האפליקציה המעודכנת תקבל גישה אל:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"האם ברצונך להתקין עדכון לאפליקציה מובנית זו? הנתונים הקיימים שלך לא יאבדו. האפליקציה המעודכנת תקבל גישה אל:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"האם ברצונך להתקין עדכון עבור אפליקציה קיימת זו? הנתונים הקיימים שלך לא יאבדו. אין צורך בגישה מיוחדת."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"האם ברצונך להתקין עדכון עבור אפליקציה מובנית זו? הנתונים הקיימים שלך לא יאבדו. אין צורך בגישה מיוחדת."</string>
+ <string name="install_failed" msgid="6579998651498970899">"האפליקציה לא הותקנה."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"החבילה נחסמה להתקנה."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"האפליקציה לא הותקנה כי החבילה מתנגשת עם חבילה קיימת."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטאבלט."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"האפליקציה הזו אינה תואמת לטלוויזיה שלך."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטלפון."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"האפליקציה לא הותקנה כי נראה שהחבילה לא תקפה."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטאבלט שלך."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטלוויזיה שלך."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטלפון שלך."</string>
+ <string name="launch" msgid="4826921505917605463">"פתח"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"מנהל המערכת שלך לא מתיר התקנה של אפליקציות ממקורות לא ידועים"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"למשתמש זה אין הרשאה להתקין אפליקציות שאינן מוכרות"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"למשתמש הזה אין הרשאה להתקין אפליקציות"</string>
+ <string name="ok" msgid="3468756155452870475">"אישור"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"נהל אפליקציות"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"אין מספיק שטח"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g>. פנה שטח ונסה שוב."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"האפליקציה לא נמצא"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"האפליקציה לא נמצאה ברשימת האפליקציות המותקנות."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"לא מורשה"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"המשתמש הנוכחי אינו מורשה להסיר את ההתקנה הזו."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"שגיאה"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"לא ניתן היה להסיר את התקנת האפליקציה."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"הסר את התקנת האפליקציה"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"הסר את התקנת העדכון"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> הוא חלק מהאפליקציה הבאה:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"האם ברצונך להסיר את ההתקנה של אפליקציה זו?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"האם אתה רוצה להסיר את האפליקציה הזו עבור "<b>"כל"</b>" המשתמשים? האפליקציה והנתונים שלה יוסרו מ"<b>"כל"</b>" המשתמשים במכשיר."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"האם ברצונך להסיר את התקנתה של אפליקציה זו עבור המשתמש <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"האם להחליף את האפליקציה הזאת בגירסת היצרן? כל הנתונים יוסרו."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"האם להחליף את האפליקציה הזאת בגירסת היצרן? כל הנתונים יוסרו. הפעולה תשפיע על כל משתמשי המכשיר, כולל משתמשים בעלי פרופיל עבודה."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"התקנות בתהליכי הסרה"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"הסרות התקנה שנכשלו"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"מסיר התקנה..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"מסיר את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"הסרת ההתקנה הסתיימה."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> הוסרה"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"הסרת התקנה נכשלה."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"נכשלה הסרת ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"לא ניתן להסיר את ההתקנה של אפליקציה פעילה של מנהל המכשיר"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"לא ניתן להסיר את ההתקנה של אפליקציה פעילה של מנהל המכשיר של <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"אפליקציה זו נדרשת לחלק מהמשתמשים או מהפרופילים והתקנתה הוסרה למשתמשים אחרים"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"האפליקציה הזו נחוצה לפרופיל שלך ולא ניתן להסיר את ההתקנה שלה."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"מנהל המכשיר שלך מחייב את קיומה של אפליקציה זו, ולא ניתן להסירה."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"אפליקציות למנהל המערכת של מכשיר מנוהל"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ניהול משתמשים"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"לא ניתן להסיר את ההתקנה של <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"אירעה בעיה בניתוח החבילה."</string>
+ <string name="newPerms" msgid="6039428254474104210">"חדש"</string>
+ <string name="allPerms" msgid="1024385515840703981">"הכל"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"פרטיות"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"גישה למכשיר"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"עדכון זה לא דורש הרשאות חדשות."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"לא, תודה"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"למידע נוסף"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"לדחות בכל מקרה"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> מתוך <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"האם לאשר ל<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"תמיד להרשות לאפליקציה <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"רק בזמן השימוש באפליקציה"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"תמיד"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"יש לדחות ואין לשאול שוב"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> הרשאות מושבתות"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"כל ההרשאות מושבתות"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"אין הרשאות מושבתות"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"כן, זה בסדר"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"אפליקציות"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"הרשאות לאפליקציות"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ראיתי פעם אחת, זה מספיק"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"אין הרשאות"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"הרשאות נוספות"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"פתיחה של פרטי האפליקציה"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="two">עוד <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">עוד <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">עוד <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">עוד <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"האפליקציה הזו עוצבה בשביל גרסה ישנה יותר של Android. דחיית ההרשאה עשויה לגרום לה לתפקד בצורה לקויה."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ביצוע פעולה לא ידועה"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> מתוך <xliff:g id="COUNT_1">%2$d</xliff:g> אפליקציות קיבלו הרשאה"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"הרשאות המערכת"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"הסתר מערכת"</string>
+ <string name="no_apps" msgid="1965493419005012569">"אין אפליקציות"</string>
+ <string name="location_settings" msgid="1774875730854491297">"הגדרות מיקום"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא ספק של שירותי מיקום בשביל המכשיר הזה. אפשר לשנות את גישת המיקום בהגדרות המיקום."</string>
+ <string name="system_warning" msgid="7103819124542305179">"אם תדחה את ההרשאה הזו, ייתכן שתכונות בסיסיות במכשיר לא יפעלו כצפוי."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"נאכף באמצעות מדיניות"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"הגישה ברקע מושבתת על ידי מדיניות"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"הגישה ברקע מופעלת על ידי מדיניות"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"הגישה בחזית מופעלת על ידי מדיניות"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"נמצא בשליטת מנהל מערכת"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"תמיד"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"רק בזמן השימוש באפליקציה"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"אף פעם"</string>
+ <string name="loading" msgid="7811651799620593731">"טוען..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"כל ההרשאות"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"הרשאות אחרות של האפליקציה"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"בקשת הרשאה"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"זוהתה שכבת על במסך"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"כדי לשנות את הגדרת ההרשאה הזו, ראשית עליך לכבות את שכבת העל במסך ב\'הגדרות\' > \'אפליקציות\'"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"פתח הגדרות"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"פעולות התקנה/הסרת התקנה אינן נתמכות ב-Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"בחר אילו הרשאות גישה ברצונך לתת ל <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> עודכנה. בחר אילו הרשאות גישה יהיו לאפליקציה זו."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"ביטול"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"המשך"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"הרשאות חדשות"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"הרשאות קיימות"</string>
+ <string name="message_staging" msgid="6151794817691100003">"מכין אפליקציה להתקנה…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"לא ידוע"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"לצורכי אבטחה, הטאבלט שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"לצורכי אבטחה, מכשיר הטלוויזיה שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"לצורכי אבטחה, הטלפון שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"נתוני הטלפון והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטלפון שלך בעקבות השימוש באפליקציה."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"נתוני הטאבלט והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטאבלט שלך בעקבות השימוש באפליקציה."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"נתוני הטלוויזיה והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטלוויזיה שלך בעקבות השימוש באפליקציה."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"המשך"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"הגדרות"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"מתקין/מסיר התקנה של אפליקציות Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ja-television/strings.xml b/packages/PackageInstaller/res/values-ja-television/strings.xml
new file mode 100644
index 0000000..9f31829
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ja-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"許可しない(次回から表示しない)"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"これは後から[設定]>[アプリ]で変更できます"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"システムアプリの表示"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"アプリの権限"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"アプリの権限"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g>の権限"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"その他の権限"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g>の権限"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ja-watch/strings.xml b/packages/PackageInstaller/res/values-ja-watch/strings.xml
new file mode 100644
index 0000000..735b908
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ja-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"許可しない(今後表示しない)"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"システムアプリの表示"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"変更不可"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"はい"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"キャンセル"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
new file mode 100644
index 0000000..5a7dc7d
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"パッケージインストーラ"</string>
+ <string name="next" msgid="3057143178373252333">"次へ"</string>
+ <string name="install" msgid="5896438203900042068">"インストール"</string>
+ <string name="done" msgid="3889387558374211719">"完了"</string>
+ <string name="cancel" msgid="8360346460165114585">"キャンセル"</string>
+ <string name="installing" msgid="8613631001631998372">"インストール中..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をインストールしています…"</string>
+ <string name="install_done" msgid="3682715442154357097">"アプリをインストールしました。"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"このアプリケーションをインストールしてもよろしいですか?このアプリケーションは下記にアクセスする場合があります:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"このアプリケーションをインストールしてもよろしいですか?このアプリケーションは特別なアクセス許可を必要としません。"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"この既存のアプリケーションへのアップデートをインストールしてもよろしいですか?既存のデータは失われません。アップデート後のアプリケーションは下記にアクセスする場合があります:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"この内蔵アプリケーションへのアップデートをインストールしてもよろしいですか?既存のデータは失われません。アップデート後のアプリケーションは下記にアクセスする場合があります:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"この既存のアプリにアップデートをインストールしますか?既存のデータが失われることはありません。特別なアクセス権も必要ありません。"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"この内蔵アプリにアップデートをインストールしますか?既存のデータが失われることはありません。特別なアクセス権も必要ありません。"</string>
+ <string name="install_failed" msgid="6579998651498970899">"アプリはインストールされていません。"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"パッケージのインストールはブロックされています。"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"パッケージが既存のパッケージと競合するため、アプリをインストールできませんでした。"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"お使いのタブレットに対応していないため、アプリをインストールできませんでした。"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"このアプリはお使いのテレビに対応していません。"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"お使いのスマートフォンに対応していないため、アプリをインストールできませんでした。"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"パッケージが無効の可能性があるため、アプリをインストールできませんでした。"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>をタブレットにインストールできませんでした。"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>をテレビにインストールできませんでした。"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>を端末にインストールできませんでした。"</string>
+ <string name="launch" msgid="4826921505917605463">"開く"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"提供元不明のアプリをインストールすることは、管理者により禁止されています"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"このユーザーは不明なアプリをインストールできません"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"このユーザーはアプリをインストールできません"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"アプリを管理"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"容量不足です"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>をインストールできませんでした。空き容量を増やしてもう一度お試しください。"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"アプリが見つかりません"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"インストール済みアプリのリストに、このアプリはありません。"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"許可されていません"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"このアンインストール操作は現在のユーザーには許可されていません。"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"エラー"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"アプリをアンインストールできませんでした。"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"アプリをアンインストール"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"アップデートをアンインストール"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>は次のアプリの一部です:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"このアプリをアンインストールしますか?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"このアプリを"<b>"すべての"</b>"ユーザーからアンインストールしますか?このアプリとそのデータは端末の"<b>"すべての"</b>"ユーザーから削除されます。"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g>さんのアプリをアンインストールしますか?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"このアプリを出荷時の状態に戻しますか?データがすべて削除されます。"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"このアプリを出荷時の状態に戻しますか?データがすべて削除されます。これは、仕事用プロファイルを設定しているユーザーも含めて、この端末を使用するすべてのユーザーが対象となります。"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"実行中のアンインストール"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"エラーになったアンインストール"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"アンインストール中..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしています…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"アンインストールが完了しました。"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしました"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"アンインストールできませんでした。"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールできませんでした。"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"有効な端末管理アプリをアンインストールできません"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> さんの有効な端末管理アプリをアンインストールできません"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"このアプリは一部のユーザーやプロファイルに必要なため、アンインストールできませんでした"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"このアプリはプロファイルに必要なため、アンインストールできません。"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"このアプリは端末管理者が必要としているため、アンインストールできません。"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"端末管理アプリを管理"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ユーザーを管理"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>をアンインストールできませんでした。"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"パッケージの解析中に問題が発生しました。"</string>
+ <string name="newPerms" msgid="6039428254474104210">"New"</string>
+ <string name="allPerms" msgid="1024385515840703981">"すべて"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"プライバシー"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"端末アクセス"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"このアップデートでは新たな許可は必要ありません。"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"許可しない"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"詳細"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"許可しない"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に<xliff:g id="ACTION">%2$s</xliff:g>を許可しますか?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"「<xliff:g id="ACTION">%2$s</xliff:g>」を <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> に常に許可しますか?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"アプリの使用中のみ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"常時"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"許可しない(次回から表示しない)"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> 件無効"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"すべて無効"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"無効な権限なし"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"許可"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"アプリ"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"アプリの権限"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"今後表示しない"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"権限がありません"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"その他の権限"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"アプリ情報を開く"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">他<xliff:g id="COUNT_1">%1$d</xliff:g>件</item>
+ <item quantity="one">他<xliff:g id="COUNT_0">%1$d</xliff:g>件</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"このアプリはAndroidの以前のバージョンを対象としています。権限を許可しないと、意図されたとおりに動作しなくなる可能性があります。"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"不明な操作の実行"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>個のアプリを許可"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"システムを表示"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"システムを表示しない"</string>
+ <string name="no_apps" msgid="1965493419005012569">"アプリなし"</string>
+ <string name="location_settings" msgid="1774875730854491297">"位置情報の設定"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g>はこの端末の位置情報サービスのプロバイダです。位置情報アクセスは位置情報の設定から変更できます。"</string>
+ <string name="system_warning" msgid="7103819124542305179">"この権限を許可しないと、お使いの端末の基本的な機能が意図されたとおりに動作しなくなる可能性があります。"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ポリシーにより適用"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"バックグラウンドでのアクセスはポリシーによって無効です"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"バックグラウンドでのアクセスはポリシーによって有効です"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"フォアグラウンドでのアクセスはポリシーによって有効です"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"管理者により管理されています"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"常時"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"アプリの使用中のみ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"なし"</string>
+ <string name="loading" msgid="7811651799620593731">"読み込んでいます…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"すべての権限"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"その他のアプリ機能"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"権限のリクエスト"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"画面オーバーレイを検出"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"この権限設定を変更するには、まず[設定]>[アプリ]から画面オーバーレイをOFFにします"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"設定を開く"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ではインストールやアンインストールができません"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」に許可する権限の選択"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"「<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>」が更新されました。このアプリに許可する権限を選択してください。"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"キャンセル"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"続行"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"新しい権限"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"現在の権限"</string>
+ <string name="message_staging" msgid="6151794817691100003">"アプリを準備しています…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"不明"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"セキュリティ上の理由から、お使いのタブレットではこの提供元からの不明なアプリをインストールすることはできません。"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"セキュリティ上の理由から、お使いのテレビではこの提供元からの不明なアプリをインストールすることはできません。"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"セキュリティ上の理由から、お使いのスマートフォンではこの提供元からの不明なアプリをインストールすることはできません。"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"不明なアプリをインストールするとスマートフォンや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるスマートフォンへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"不明なアプリをインストールするとタブレットや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるタブレットへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"不明なアプリをインストールすると TV や個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性がある TV への損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"続行"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"設定"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear アプリのインストールとアンインストール"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ka-television/strings.xml b/packages/PackageInstaller/res/values-ka-television/strings.xml
new file mode 100644
index 0000000..b7d03b0
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ka-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"უარყავი და აღარ მკითხო"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ამის შეცვლა მოგვიანებით შეგიძლიათ სექციაში პარამეტრები > აპები"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"სისტემის აპების ჩვენება"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"აპის ნებართვები"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"აპის ნებართვები"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"ნებართვები (<xliff:g id="PERMISSION">%1$s</xliff:g>)"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"დამატებითი ნებართვები"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"ნებართვები (<xliff:g id="PERMISSION">%1$s</xliff:g>)"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ka-watch/strings.xml b/packages/PackageInstaller/res/values-ka-watch/strings.xml
new file mode 100644
index 0000000..1574912
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ka-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"უარყავი და აღარ მკითხო"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"სისტემის აპების ჩვენება"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ვერ შეიცვლება"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"დიახ"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"გაუქმება"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml
new file mode 100644
index 0000000..997f95c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ka/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"პაკეტის ინსტალერი"</string>
+ <string name="next" msgid="3057143178373252333">"შემდეგი"</string>
+ <string name="install" msgid="5896438203900042068">"დაყენება"</string>
+ <string name="done" msgid="3889387558374211719">"დასრულდა"</string>
+ <string name="cancel" msgid="8360346460165114585">"გაუქმება"</string>
+ <string name="installing" msgid="8613631001631998372">"მიმდინარეობს ინსტალაცია…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის ინსტალაცია…"</string>
+ <string name="install_done" msgid="3682715442154357097">"აპი დაყენებულია."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"გსურთ, ამ აპლიკაციის დაყენება? მას ექნება წვდომა:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"გსურთ ამ აპლიკაციის დაყენება? ის არ მოითხოვს რაიმე განსაკუთრებულ ნებართვას."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"გსურთ განახლების დაყენება ამ არსებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. განახლებულ აპლიკაციას წვდომა ექნება:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"გსურთ განახლების დაყენება ამ ჩაშენებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. განახლენულ აპლიკაციას წვდომა ექნება:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"გსურთ განახლების დაყენება ამ არსებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. ის არ საჭიროებს რაიმე განსაკუთრებულ წვდომას:"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"გსურთ განახლების დაყენება ამ ჩაშენებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. ის არ საჭიროებს რაიმე განსაკუთრებულ წვდომას:"</string>
+ <string name="install_failed" msgid="6579998651498970899">"აპი არ არის დაყენებული."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ამ პაკეტის ინსტალაცია დაბლოკილია."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"აპი ვერ დაინსტალირდა, რადგან პაკეტი კონფლიქტშია არსებულ პაკეტთან."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"აპი ვერ დაინსტალირდა, რადგან ის არ არის თავსებადი თქვენს ტაბლეტთან."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ეს აპი არ არის თავსებადი თქვენს ტელევიზორთან."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"აპი ვერ დაინსტალირდა, რადგან ის არ არის თავსებადი თქვენს ტელეფონთან."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"აპი ვერ დაინსტალირდა, რადგან პაკეტი, სავარაუდოდ, არასწორია."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის დაყენება თქვენს ტაბლეტზე ვერ მოხერხდა."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ვერ დაინსტალირდება თქვენს ტელევიზორში."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის დაყენება თქვენს ტელეფონზე ვერ მოხერხდა."</string>
+ <string name="launch" msgid="4826921505917605463">"გახსნა"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"უცნობი წყაროებიდან ჩამოტვირთული აპების ინსტალაცია თქვენი ადმინისტრატორის მიერ ნებადართული არ არის"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ამ მომხმარებელს უცნობი აპების ინსტალაცია არ შეუძლია"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ამ მომხმარებელს აპების დაინსტალირების უფლება არ აქვს"</string>
+ <string name="ok" msgid="3468756155452870475">"კარგი"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"აპების მართვა"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"სივრცე შეივსო"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის დაყენება შეუძლებელია. გაათავისუფლეთ მეხსიერება და სცადეთ ხელახლა."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"აპი ვერ მოიძებნა."</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"დაყენებული აპების სიაში ეს აპი ვერ მოიძებნა."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"დაუშვებელია"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"მიმდინარე მომხმარებელს არ აქვს დეინსტალაციის განხორციელების უფლება."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"შეცდომა"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"აპის დეინსტალაცია ვერ მოხერხდა."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"აპის დეინსტალაცია"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"განახლების დეინსტალაცია"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> არის შემდეგი აპის ნაწილი:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"გსურთ, ამ აპის დეინსტალაცია?"</string>
+ <!-- syntax error in translation for uninstall_application_text_all_users (5574704453233525222) org.xmlpull.v1.XmlPullParserException: expected: /string read: b (position:END_TAG </b>@1:122 in <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"გსურთ ამ აპის დეინსტალაცია ყველა"</b>" მომხმარებილის "<b>"-თვის? აპლიკაცია და მისი მონაცემენბი წაიშლება ყველა"</b>" მომხმარებლის "<b>"-თვის მოწყობილობაზე."</string>
+) -->
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"გსურთ <xliff:g id="USERNAME">%1$s</xliff:g> მომხმარებლისათვის ამ აპის დეინსტალაცია?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"გსურთ ამ აპის ქარხნული ვერსიით ჩანაცვლება? მონაცემები მთლიანად ამოიშლება."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"გსურთ ამ აპის ქარხნული ვერსიით ჩანაცვლება? მონაცემები მთლიანად ამოიშლება. ეს მოქმედება გავლენას იქონიებს ამ მოწყობილობის ყველა მომხმარებელზე, მათ შორის, სამსახურის პროფილებით მოსარგებლეებზეც."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"გაშვებული დეინსტალაციები"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"შეუსრულებელი დეინსტალაციები"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"დეინსტალაცია…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"დეინსტალაცია დასრულდა."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> დეინსტალირებულია"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"დეინსტალაცია წარუმატებელია."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია ვერ მოხერხდა."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"მოწყობილობის ადმინისტრატორის აქტიური აპის დეინსტალაცია ვერ მოხერხდება"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>-სთვის მოწყობილობის ადმინისტრატორის აქტიური აპის დეინსტალაცია ვერ მოხერხდება"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ამ აპს მომხმარებლების/პროფილების ნაწილი იყენებს. სხვებისთვის ის დეინსტალირებულია."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ეს აპი საჭიროა თქვენი პროფილისთვის. მისი დეინსტალაცია ვერ მოხერხდება."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ეს აპი საჭიროა თქვენი მოწყ. ადმინისტრატორისათვის და დეინსტალაცია ვერ გამოვა."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"მოწყობილობის ადმინისტრატორების აპების მართვა"</string>
+ <string name="manage_users" msgid="3125018886835668847">"მომხმარებლების მართვა"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> -ის დეინსტალაცია ვერ მოხერხდა."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"პაკეტის ანალიზისას წარმოიშვა პრობლემა."</string>
+ <string name="newPerms" msgid="6039428254474104210">"ახალი"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ყველა"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"კონფიდენციალურობა"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"მოწყობილობის წვდომა"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ეს განახლება არ საჭიროებს ახალ ნებართვებს."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"უარყოფა"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"დამატებითი ინფორმაცია"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"მაინც უარყოფა"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-დან"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"გსურთ, დაუშვათ, რომ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-მ შეასრულოს <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"გსურთ, ყოველთვის შესრულდეს <xliff:g id="ACTION">%2$s</xliff:g> <b><xliff:g id="APP_NAME">%1$s</xliff:g>-ის</b> მიერ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"მხოლოდ აპის გამოყენებისას"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ყოველთვის"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"უარყავი და აღარ მკითხო"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"გათიშულია <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"გათიშულია ყველა"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"არაფერია გათიშული"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"დაშვება"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"აპები"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"აპის უფლებები"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"აღარ მკითხოთ"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ნებართვები არ არის"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"დამატებითი ნებართვები"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"აპის ინფორმაციის გახსნა"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> კიდევ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> კიდევ</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ეს აპი Android-ის ძველი ვერსიისთვის შეიქმნა. ნებართვის უარყოფამ შესაძლოა მისი არასათანადო ფუნქციონირება გამოიწვიოს."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"უცნობი ქმედების შესრულება"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"დაშვებულია <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> აპიდან"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"სისტემის ჩვენება"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"სისტემური პროცესების დამალვა"</string>
+ <string name="no_apps" msgid="1965493419005012569">"აპები არ არის"</string>
+ <string name="location_settings" msgid="1774875730854491297">"მდებარეობის პარამეტრები"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> არის მდებარეობის სერვისების მომწოდებელი ამ მოწყობილობისთვის. მდებარეობაზე წვდომის შეცვლა შესაძლებელია მდებარეობის პარამეტრებიდან."</string>
+ <string name="system_warning" msgid="7103819124542305179">"ამ ნებართვის უარყოფის შემთხვევაში, თქვენი მოწყობილობის ძირითადმა ფუნქციებმა შესაძლოა სათანადოდ აღარ იმუშაოს."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"შეესაბამება წესს"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ფონზე წვდომა დებულებით გათიშულია"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ფონზე წვდომა დებულებით დაშვებულია"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"წინა პლანზე წვდომა დებულებით დაშვებულია"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"იმართება ადმინისტრატორის მიერ"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ყოველთვის"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"მხოლოდ აპის გამოყენებისას"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"არასოდეს"</string>
+ <string name="loading" msgid="7811651799620593731">"იტვირთება..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"ყველა ნებართვა"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"აპის სხვა შესაძლებლობები"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"ნებართვის მოთხოვნა"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"ეკრანის გადაფარვა გამოვლინდა"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ამ ნებართვის პარამეტრის შესაცვლელად, ჯერ უნდა გამორთოთ ეკრანის გადაფარვა პარამეტრებიდან > აპებიდან"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"პარამეტრების გახსნა"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ინსტალაციის/დეინსტალაციის მოქმედებები არ არის მხარდაჭერილი Wear-ზე."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"აირჩიეთ, რაზე ჰქონდეს წვდომა <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-ს"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> განახლდა. აირჩიეთ, რაზე ჰქონდეს წვდომა ამ აპს."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"გაუქმება"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"გაგრძელება"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"ახალი ნებართვები"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"ამჟამინდელი ნებართვები"</string>
+ <string name="message_staging" msgid="6151794817691100003">"მიმდინარეობს აპის შუალედური შენახვა…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"უცნობი"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"თქვენივე უსაფრთხოებისთვის, ტაბლეტს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება არ აქვს."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"თქვენივე უსაფრთხოებისთვის, ტელევიზორს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება არ აქვს."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"თქვენივე უსაფრთხოებისთვის, ტელეფონს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება არ აქვს."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"თქვენი ტელეფონი და პირადი მონაცემები უცნობი აპების შემოტევების წინაშე მეტად დაუცველია. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტელეფონისთვის მიყენებულ ზიანსა და მონაცემების დაკარგვაზე."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"თქვენი ტელეფონი და პირადი მონაცემები უცნობი აპების შემოტევების წინაშე მეტად დაუცველია. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტაბლეტისთვის მიყენებულ ზიანსა და მონაცემების დაკარგვაზე."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"თქვენი ტელევიზორი და პირადი მონაცემები უცნობი აპების შემოტევების წინაშე მეტად დაუცველია. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტელევიზორისთვის მიყენებულ ზიანსა და მონაცემების დაკარგვაზე."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"გაგრძელება"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"პარამეტრები"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear აპების ინსტალაცია/დეინსტალაცია"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-kk-television/strings.xml b/packages/PackageInstaller/res/values-kk-television/strings.xml
new file mode 100644
index 0000000..2d0ff43
--- /dev/null
+++ b/packages/PackageInstaller/res/values-kk-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Тыйым салу және қайтадан сұрамау"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Мұны кейінірек \"Параметрлер\" және \"Қолданбалар\" ішінен өзгертуге болады"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Жүйелік қолданбаларды көрсету"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Қолданба рұқсаттары"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Қолданба рұқсаттары"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> рұқсаттары"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Қосымша рұқсаттар"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> рұқсаттары"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-kk-watch/strings.xml b/packages/PackageInstaller/res/values-kk-watch/strings.xml
new file mode 100644
index 0000000..8996bcb
--- /dev/null
+++ b/packages/PackageInstaller/res/values-kk-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Тыйым салу, қайтадан сұрамау"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Жүйелік қолданбаларды көрсету"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Өзгерту мүмкін емес"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Иә"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Бас тарту"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml
new file mode 100644
index 0000000..26892e1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-kk/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Бума орнатқыш"</string>
+ <string name="next" msgid="3057143178373252333">"Келесі"</string>
+ <string name="install" msgid="5896438203900042068">"Орнату"</string>
+ <string name="done" msgid="3889387558374211719">"Дайын"</string>
+ <string name="cancel" msgid="8360346460165114585">"Бас тарту"</string>
+ <string name="installing" msgid="8613631001631998372">"Орнатуда…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> орнатылуда…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Қолданба орнатылды."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Бұл қолданбаны орнатуды қалайсыз ба? Оның келесі нәрселерге қол жетімділігі болады:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Бұл қолданбаны орнатуды қалайсыз ба? Ол ерекше қол жетімділікті қажет етпейді."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Бұл қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Жаңартылған қолданбаның келесі нәрселерге қол жетімділігі болады:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Бұл орнатылған қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Жаңартылған қолданбаның келесі нәрселерге қол жетімділігі болады:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Бұл қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Ол ерекше қол жетімділікті қажет етпейді."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Бұл орнатылған қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Ол ерекше қол жетімділікті қажет етпейді."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Қолданба орнатылмады."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Буманы орнатуға тыйым салынды."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Пакет түрінде орнатылмаған қолданба мен бұрыннан бар пакеттің арасында қайшылық туындайды."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Қолданба түрінде орнатылмаған қолданба, планшетіңізбен үйлесімді емес."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Бұл қолданба теледидарыңызбен үйлесімді емес."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Қолданба түрінде орнатылмаған қолданба, телефоныңызбен үйлесімді емес."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Пакет түрінде орнатылмаған қолданба жарамсыз болып табылады."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын планшетіңізге орнату мүмкін емес"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> теледидарыңызда орнату мүмкін емес."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын телефоныңызға орнату мүмкін емес."</string>
+ <string name="launch" msgid="4826921505917605463">"Ашу"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Әкімші белгісіз көздерден алынған қолданбаларды орнатуға рұқсат етпейді"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Бұл пайдаланушы белгісіз қолданбаларды орната алмайды"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Бұл пайдаланушының қолданбаларды орнату рұқсаты жоқ"</string>
+ <string name="ok" msgid="3468756155452870475">"Жарайды"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Қолданбаларды басқару"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Орнында емес"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын орнату мүмкін болмады. Орын босатып, қайта әрекеттеніп көріңіз."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Қолданба табылмады"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Қолданба орнатылған қолданбалар тізімінен табылмады."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Рұқсат етілмеген"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Ағымдағы пайдаланушыға бұл жою әрекетіне рұқсат берілмеген."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Қате"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Қолданба жойылмады."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Қолданбаны алып тастау"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Жаңартуды алып тастау"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> келесі қолданбаның бөлігі:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Бұл қолданбаны алып тастауды қалайсыз ба?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Бұл қолданбаны "<b>"барлық"</b>" пайдаланушылар үшін алып тастауды қалайсыз ба? Қолданба және оның деректері құрылғыдағы "<b>"барлық"</b>" пайдаланушылардан алынады."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Пайдаланушы <xliff:g id="USERNAME">%1$s</xliff:g> үшін осы қолданбаны жою керек пе?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Бүкіл деректер жойылады."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Бүкіл деректер жойылады. Бұл осы құрылғының барлық пайдаланушыларына, соның ішінде жұмыс профильдері бар пайдаланушыларға әсер етеді."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Жұмыс істеп тұрған жою әрекеттері"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Сәтсіз жою әрекеттері"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Алып тастау орындалуда..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылуда…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Алып тастау аяқталды."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылды"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Алып тастау сәтсіздікке ұшырады."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жою сәтсіз аяқталды."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Белсенді құрылғының әкімші қолданбасын жою мүмкін емес"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> үшін белсенді құрылғының әкімші қолданбасын жою мүмкін емес"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Бұл қолданба кейбір пайдаланушылар немесе профильдер үшін қажет және басқалар үшін жойылды"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Бұл қолданба профиліңіз үшін қажет және оны жою мүмкін емес."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Әкімші осы қолданбаны талап етеді және оны жою мүмкін емес."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Құрылғы әкімшісі қолданбаларын басқару"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Пайдаланушыларды басқару"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын алып тастау мүмкін емес."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Жинақты сараптау кезінде мәселе орын алды."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Жаңа"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Барлық"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Құпиялылық"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Құралға кіру"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Бұл қолданба жаңа рұқсаттарды қажет етпейді."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Тыйым салу"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Қосымша ақпарат"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Бәрібір рұқсат бермеу"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>/<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасына <xliff:g id="ACTION">%2$s</xliff:g> рұқсатын беру керек пе?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> қолданбасы үшін <xliff:g id="ACTION">%2$s</xliff:g> әрекетіне әрқашан рұқсат етілсін бе?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Қолданба пайдаланылғанда ғана"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Әрқашан"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Тыйым салынсын және қайта сұралмасын"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> рұқсат өшірілді"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"барлық рұқсаттар өшірілді"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"рұқсаттардың ешқайсысы өшірілмеді"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Рұқсат беру"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Қолданбалар"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Қолданба рұқсаттары"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Қайта сұралмасын"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Рұқсат жоқ"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Қосымша рұқсаттар"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Қолданба ақпаратын ашу"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Тағы <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Тағы <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Бұл қолданба Android жүйесінің ескі нұсқасына арналған. Рұқсаттан бас тартсаңыз, бұдан былай тиісінше жұмыс істемеуі мүмкін."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"белгісіз әрекетті орындау"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> қолданбаға рұқсат етілген"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Жүйені көрсету"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Жүйені жасыру"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Қолданбалар жоқ"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Орынды анықтау параметрлері"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> — осы құрылғыға орынды анықтау қызметтерін көрсететін қолданба. Орынды пайдалану мүмкіндігін орынды анықтау параметрлерінде өзгертуге болады."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Бұл рұқсатты бермесеңіз, құрылғының негізгі функциялары енді көзделгендей жұмыс істемеуі мүмкін."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Саясат арқылы қолданылған"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Саясат бойынша фондық режимде кіруге рұқсат етілмеген"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Саясат бойынша фондық режимде кіруге рұқсат етілген"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Саясат бойынша экрандық режимде кіруге рұқсат етілген"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Әкімші басқарады"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Әрқашан"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Қолданба пайдаланылғанда ғана"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Ешқашан"</string>
+ <string name="loading" msgid="7811651799620593731">"Жүктелуде…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Барлық рұқсаттар"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Басқа қолданба мүмкіндіктері"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Рұқсат сұрау"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Экранды қабаттастыру анықталды"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Бұл рұқсат параметрін өзгерту үшін алдымен «Параметрлер» > «Қолданбалар» тармағында экранды қабаттастыруды өшіру керек"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Параметрлерді ашу"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear құрылғысында \"Орнату\"/\"Жою\" әрекеттері қолданылмайды."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы қайда кіре алатынын таңдаңыз"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы жаңартылды. Бұл қолданбаның қайда кіре алатынын таңдаңыз."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Бас тарту"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Жалғастыру"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Жаңа рұқсаттар"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Ағымдағы рұқсаттар"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Қолданба реттелуде…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Белгісіз"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Қауіпсіздікті сақтау үшін планшетке бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Қауіпсіздікті сақтау үшін теледидарға бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Қауіпсіздікті сақтау үшін телефонға бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефон және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі телефонға келетін залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Планшет және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі планшетке келетін залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Теледидар және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі теледидарға келетін қандай да бір залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Жалғастыру"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Параметрлер"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear қолданбасын орнату/жою"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-km-television/strings.xml b/packages/PackageInstaller/res/values-km-television/strings.xml
new file mode 100644
index 0000000..f02744d
--- /dev/null
+++ b/packages/PackageInstaller/res/values-km-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"បដិសេធ ហើយកុំសួរម្តងទៀត"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"អ្នកអាចប្តូរវាពេលក្រោយនៅក្នុងការកំណត់ > កម្មវិធី"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"បង្ហាញកម្មវិធីប្រព័ន្ធ"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"សិទ្ធិអនុញ្ញាតកម្មវិធី"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"សិទ្ធិអនុញ្ញាតកម្មវិធី"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"សិទ្ធិអនុញ្ញាត <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"ការអនុញ្ញាតបន្ថែម"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"សិទ្ធិអនុញ្ញាត <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-km-watch/strings.xml b/packages/PackageInstaller/res/values-km-watch/strings.xml
new file mode 100644
index 0000000..c5f49c5
--- /dev/null
+++ b/packages/PackageInstaller/res/values-km-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"បដិសេធ សូមកុំសួរម្តងទៀត"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"បង្ហាញកម្មវិធីប្រព័ន្ធ"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"មិនអាចប្តូរបានទេ"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"បាទ/ចាស"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"បោះបង់"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml
new file mode 100644
index 0000000..693ea32
--- /dev/null
+++ b/packages/PackageInstaller/res/values-km/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"កម្មវិធីដំឡើងកញ្ចប់"</string>
+ <string name="next" msgid="3057143178373252333">"បន្ទាប់"</string>
+ <string name="install" msgid="5896438203900042068">"ដំឡើង"</string>
+ <string name="done" msgid="3889387558374211719">"រួចរាល់"</string>
+ <string name="cancel" msgid="8360346460165114585">"បោះបង់"</string>
+ <string name="installing" msgid="8613631001631998372">"កំពុងដំឡើង..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"កំពុងដំឡើង <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"បានដំឡើងកម្មវិធី។"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"តើអ្នកចង់ដំឡើងកម្មវិធីនេះ? វានឹងមានសិទ្ធិចូល៖"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"តើអ្នកចង់ដំឡើងកម្មវិធីនេះ? វាមិនទាមទារសិទ្ធិចូលពិសេសទេ។"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"តើអ្នកចង់ដំឡើងបច្ចុប្បន្នភាពកម្មវិធីដែលមានស្រាប់នេះ? ទិន្នន័យដែលមានស្រាប់របស់អ្នកនឹងមិនបាត់បង់ទេ។ កម្មវិធីបានធ្វើបច្ចុប្បន្នភាពនឹងចូលដំណើរការទៅ៖"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"តើអ្នកចង់ដំឡើងបច្ចុប្បន្នភាពកម្មវិធីដែលជាប់ជាមួយនេះ? ទិន្នន័យដែលមានស្រាប់របស់អ្នកនឹងមិនបាត់បង់ទេ។ កម្មវិធីបានធ្វើបច្ចុប្បន្នភាពហើយនឹងមានសិទ្ធិចូល៖"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"តើអ្នកចង់ដំឡើងបច្ចុប្បន្នភាពកម្មវិធីដែលមានស្រាប់នេះ? ទិន្នន័យដែលមានស្រាប់របស់អ្នកនឹងមិនបាត់បង់ទេ។ វាមិនទាមទារការចូលដំណើរការពិសេសណាមួយទេ។"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"តើអ្នកចង់ដំឡើងបច្ចុប្បន្នភាពកម្មវិធីដែលជាប់ជាមួយ? ទិន្នន័យដែលមានស្រាប់របស់អ្នកនឹងមិនបាត់បង់ទេ។ វាមិនទាមទារការចូលដំណើរការពិសេសណាមួយទេ។"</string>
+ <string name="install_failed" msgid="6579998651498970899">"មិនបានដំឡើងកម្មវិធី។"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"កញ្ចប់នេះត្រូវបានរារាំងមិនឲ្យដំឡើង"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់កម្មវិធីមិនត្រូវគ្នាជាមួយកញ្ចប់ដែលមានស្រាប់។"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកម្មវិធីមិនត្រូវគ្នាជាមួយថេប្លេតរបស់អ្នក។"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"កម្មវិធីនេះមិនត្រូវគ្នាជាមួយទូរទស្សន៍របស់អ្នកទេ"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកម្មវិធីមិនត្រូវគ្នាជាមួយទូរសព្ទរបស់អ្នក។"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់គ្មានសុពលភាព។"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"មិនអាចដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> ក្នុងកុំព្យូទ័របន្ទះរបស់អ្នក។"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចដំឡើងនៅលើទូរទស្សន៍របស់អ្នកទេ។"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"មិនអាចដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> ក្នុងទូរស័ព្ទរបស់អ្នក។"</string>
+ <string name="launch" msgid="4826921505917605463">"បើក"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"អ្នកគ្រប់គ្រងរបស់អ្នកមិនអនុញ្ញាតឲ្យដំឡើងកម្មវិធីដែលបានមកពីប្រភពដែលមិនស្គាល់ទេ"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"កម្មវិធីដែលមិនស្គាល់មិនអាចដំឡើងដោយអ្នកប្រើប្រាស់នេះបានទេ"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"អ្នកប្រើប្រាស់នេះមិនត្រូវបានអនុញ្ញាតឲ្យដំឡើងកម្មវិធីទេ"</string>
+ <string name="ok" msgid="3468756155452870475">"យល់ព្រម"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"គ្រប់គ្រងកម្មវិធី"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"អស់ទំហំ"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"មិនអាចដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> ។ លុបឯកសារខ្លះ ហើយព្យាយាមម្ដងទៀត។"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"រកមិនឃើញកម្មវិធី"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"រកមិនឃើញកម្មវិធីក្នុងបញ្ជីកម្មវិធីបានដំឡើង។"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"មិនបានអនុញ្ញាត"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"អ្នកប្រើបច្ចុប្បន្នមិនមានការអនុញ្ញាតឱ្យធ្វើការលុបនេះទេ។"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"បញ្ហា"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"មិនអាចលុបកម្មវិធីនេះបានទេ។"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"លុបកម្មវិធី"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"លុបបច្ចុប្បន្នភាព"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ជាផ្នែកមួយនៃកម្មវិធីដូចខាងក្រោមនេះ៖"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"តើអ្នកចង់លុបកម្មវិធីនេះឬ?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"តើអ្នកចង់លុបកម្មវិធីនេះសម្រាប់អ្នកប្រើ "<b>"ទាំងអស់"</b>"? កម្មវិធី និងទិន្នន័យរបស់វានឹងត្រូវបានលុបចេញពីអ្នកប្រើ "<b>"ទាំងអស់"</b>" ក្នុងឧបករណ៍នេះ។"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"តើអ្នកចង់លុបកម្មវិធីនេះសម្រាប់អ្នកប្រើ <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ជំនួសកម្មវិធីនេះដោយកំណែរោងចក្រឬ? ទិន្នន័យទាំងអស់នឹងត្រូវបានលុបចេញ។"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ជំនួយកម្មវិធីនេះដោយកំណែរោងចក្រឬ? ទិន្នន័យទាំងអស់នឹងត្រូវបានលុបចេញ។ វាប៉ះពាល់ដល់អ្នកប្រើឧបករណ៍នេះទាំងអស់ ដោយរាប់បញ្ចូលទាំងអ្នកប្រើដែលមានប្រវត្តិរូបការងារផងដែរ។"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"កំពុងដំណើរការការលុប"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"មិនអាចធ្វើការលុបបានទេ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"កំពុងលុប..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"កំពុងលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"បានបញ្ចប់ការលុប។"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"បានលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ការលុបបរាជ័យ។"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"មិនអាចលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> បាន។"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"មិនអាចលុបកម្មវិធីអ្នកគ្រប់គ្រងឧបករណ៍ដែលបានដំណើរការបានទេ"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"មិនអាចលុបកម្មវិធីអ្នកគ្រប់គ្រងឧបករណ៍សម្រាប់ <xliff:g id="USERNAME">%1$s</xliff:g> ដែលបានដំណើរការបានទេ"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"កម្មវិធីនេះតម្រូវឲ្យមានសម្រាប់អ្នកប្រើ ឬប្រវត្តិរូបមួយចំនួន និងត្រូវបានលុបសម្រាប់អ្នកប្រើផ្សេងទៀត"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"កម្មវិធីនេះចាំបាច់សម្រាប់ប្រវតិ្តការងាររបស់អ្នក ហើយវាមិនអាចលុបបានទេ។"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"កម្មវិធីនេះត្រូវបានទាមទារដោយអ្នកគ្រប់គ្រងឧបករណ៍របស់អ្នក ហើយមិនអាចលុបចេញបានទេ។"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"គ្រប់គ្រងកម្មវិធីអ្នកគ្រប់គ្រងឧបករណ៍"</string>
+ <string name="manage_users" msgid="3125018886835668847">"គ្រប់គ្រងអ្នកប្រើ"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"មិនអាចលុប <xliff:g id="APP_NAME">%1$s</xliff:g> ។"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"មានបញ្ហាក្នុងការញែកកញ្ចប់។"</string>
+ <string name="newPerms" msgid="6039428254474104210">"ថ្មី"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ទាំងអស់"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ភាពឯកជន"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ការចូលដំណើរការឧបករណ៍"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"បច្ចុប្បន្នភាពនេះមិនទាមទារសិទ្ធិថ្មីទេ។"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"បដិសេធ"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ព័ត៌មានបន្ថែម"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"បដិសេធទោះយ៉ាងណាក៏ដោយ"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> នៃ <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"អនុញ្ញាតឲ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"អនុញ្ញាតឱ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g> ជានិច្ចមែនទេ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ខណៈពេលប្រើកម្មវិធីតែប៉ុណ្ណោះ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ជានិច្ច"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"បដិសេធ ហើយកុំសួរម្តងទៀត"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"បានបិទ <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"បានបិទទាំងអស់"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"មិនបានបិទអ្វីទាំងអស់"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"អនុញ្ញាត"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"កម្មវិធី"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ការអនុញ្ញាតកម្មវិធី"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"កុំសួរទៀត"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"គ្មានសិទ្ធិអនុញ្ញាត"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"ការអនុញ្ញាតបន្ថែម"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"បើកព័ត៌មានកម្មវិធី"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ទៀត</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ទៀត</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"កម្មវិធីនេះត្រូវបានរចនាឡើងសម្រាប់កំណែចាស់របស់ Android។ ការបដិសេធសិទ្ធិអនុញ្ញាតអាចបណ្តាលឲ្យវាបំពេញមុខងារមិនដូចអ្វីដែលគេរំពឹងទុកតទៅទៀតទេ។"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ប្រតិបត្តិការសកម្មភាពមិនស្គាល់"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"បានអនុញ្ញាតកម្មវិធី <xliff:g id="COUNT_0">%1$d</xliff:g> នៃ <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"បង្ហាញប្រព័ន្ធ"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"លាក់ប្រព័ន្ធ"</string>
+ <string name="no_apps" msgid="1965493419005012569">"គ្មានកម្មវិធី"</string>
+ <string name="location_settings" msgid="1774875730854491297">"ការកំណត់ទីតាំង"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាអ្នកផ្តល់សេវាកម្មទីតាំងសម្រាប់ឧបករណ៍នេះ។ ការចូលដំណើរការទីតាំងអាចកែសម្រួលបានចេញពីការកំណត់ទីតាំង។"</string>
+ <string name="system_warning" msgid="7103819124542305179">"ប្រសិនបើអ្នកបដិសេធសិទ្ធិអនុញ្ញាតនេះ លក្ខណៈពិសេសគោលនៃឧបករណ៍របស់អ្នកអាចមិនដំណើរការដូចដែលអ្នកចង់បានតទៅទៀតទេ។"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"អនុវត្តតាមគោលការណ៍"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ការចូលប្រើផ្ទៃខាងក្រោយត្រូវបានបិទដោយគោលការណ៍"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ការចូលប្រើផ្ទៃខាងក្រោយត្រូវបានបើកដោយគោលការណ៍"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ការចូលប្រើផ្ទៃខាងមុខត្រូវបានបើកដោយគោលការណ៍"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ជានិច្ច"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ខណៈពេលប្រើកម្មវិធីតែប៉ុណ្ណោះ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"កុំឱ្យសោះ"</string>
+ <string name="loading" msgid="7811651799620593731">"កំពុងដំណើរការ..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"សិទ្ធិអនុញ្ញាតទាំងអស់"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"សមត្ថភាពកម្មវិធីផ្សេងទៀត"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"សំណើសុំសិទ្ធិអនុញ្ញាត"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"បានរកឃើញអេក្រង់ត្រួតគ្នា"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ដើម្បីប្តូរការកំណត់សិទ្ធិអនុញ្ញាតនេះ ជាដំបូងអ្នកត្រូវបិទអេក្រង់ត្រួតគ្នានៅក្នុង ការកំណត់ > កម្មវិធី"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"បើកការកំណត់"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"សកម្មភាពដំឡើង/លុបការដំឡើងមិនគាំទ្រនៅលើ Wear ទេ"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"ជ្រើសរើសអ្វីដែលត្រូវអនុញ្ញាតឲ្យ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ចូលដំណើរការ"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ត្រូវបានអាប់ដេត។ ជ្រើសរើសអ្វីដែលត្រូវអនុញ្ញាតឲ្យកម្មវិធីនេះចូលដំណើរការ។"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"បោះបង់"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"បន្ត"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"សិទ្ធិអនុញ្ញាតថ្មី"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"សិទ្ធិអនុញ្ញាតបច្ចុប្បន្ន"</string>
+ <string name="message_staging" msgid="6151794817691100003">"កំពុងសាកល្បងកម្មវិធី…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"មិនស្គាល់"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ដើម្បីការពារសុវតិ្ថភាពរបស់អ្នក ថេប្លេតរបស់អ្នកមិនត្រូវបានអនុញ្ញាតឲ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ដើម្បីការពារសុវតិ្ថភាពរបស់អ្នក ទូរទស្សន៍របស់អ្នកមិនត្រូវបានអនុញ្ញាតឲ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ដើម្បីការពារសុវតិ្ថភាពរបស់អ្នក ទូរសព្ទរបស់អ្នកមិនត្រូវបានអនុញ្ញាតឲ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ទូរសព្ទ និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតណាមួយចំពោះទូរសព្ទ ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្តាលមកពីការប្រើប្រាស់កម្មវិធីនោះ។"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ថេប្លេត និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតណាមួយចំពោះថេប្លេត ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្តាលមកពីការប្រើប្រាស់កម្មវិធីនោះ។"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ទូរទស្សន៍ និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតណាមួយចំពោះទូរទស្សន៍ ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្តាលមកពីការប្រើប្រាស់កម្មវិធីនោះ។"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"បន្ត"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ការកំណត់"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"ការដំឡើង/ការលុបកម្មវិធីឧបករណ៍ពាក់"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-kn-television/strings.xml b/packages/PackageInstaller/res/values-kn-television/strings.xml
new file mode 100644
index 0000000..2af5a4b
--- /dev/null
+++ b/packages/PackageInstaller/res/values-kn-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"ನಿರಾಕರಿಸಿ ಹಾಗೂ ಮತ್ತೊಮ್ಮೆ ಕೇಳಬೇಡ"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ನೀವು ಇದನ್ನು ನಂತರದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್ಗಳು > ಅಪ್ಲಿಕೇಶನ್ಗಳಲ್ಲಿ ಬದಲಾಯಿಸಬಹುದು"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"ಸಿಸ್ಟಂ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ತೋರಿಸು"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಗಳು"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಗಳು"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> ಅನುಮತಿಗಳು"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"ಹೆಚ್ಚುವರಿ ಅನುಮತಿಗಳು"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> ಅನುಮತಿಗಳು"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-kn-watch/strings.xml b/packages/PackageInstaller/res/values-kn-watch/strings.xml
new file mode 100644
index 0000000..1a9a993
--- /dev/null
+++ b/packages/PackageInstaller/res/values-kn-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ನಿರಾಕರಿಸಿ, ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"ಸಿಸ್ಟಂ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ತೋರಿಸು"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ಬದಲಾಯಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ಹೌದು"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"ರದ್ದುಮಾಡಿ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml
new file mode 100644
index 0000000..f42035c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-kn/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"ಪ್ಯಾಕೇಜ್ ಸ್ಥಾಪಕ"</string>
+ <string name="next" msgid="3057143178373252333">"ಮುಂದೆ"</string>
+ <string name="install" msgid="5896438203900042068">"ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+ <string name="done" msgid="3889387558374211719">"ಮುಗಿದಿದೆ"</string>
+ <string name="cancel" msgid="8360346460165114585">"ರದ್ದುಮಾಡಿ"</string>
+ <string name="installing" msgid="8613631001631998372">"ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲಾಗಿದೆ."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಇದು ಇಲ್ಲಿಗೆ ಪ್ರವೇಶ ಪಡೆದುಕೊಳ್ಳುತ್ತದೆ:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಇದಕ್ಕೆ ಯಾವುದೇ ವಿಶೇಷ ಪ್ರವೇಶದ ಅಗತ್ಯವಿಲ್ಲ."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"ನೀವು ಈ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅಪ್ಲಿಕೇಶನ್ನ ಅಪ್ಡೇಟ್ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಅಪ್ಡೇಟ್ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಇಲ್ಲಿಗೆ ಪ್ರವೇಶ ಪಡೆದುಕೊಳ್ಳುತ್ತದೆ:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ನೀವು ಈ ಬಿಲ್ಟ್-ಇನ್-ಅಪ್ಲಿಕೇಶನ್ನ ಅಪ್ಡೇಟ್ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಿಕೊಳ್ಳಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಅಪ್ಡೇಟ್ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಇಲ್ಲಿಗೆ ಪ್ರವೇಶ ಪಡೆದುಕೊಳ್ಳುತ್ತದೆ:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ನೀವು ಈ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅಪ್ಲಿಕೇಶನ್ನ ಅಪ್ಡೇಟ್ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಇದಕ್ಕೆ ಯಾವುದೇ ವಿಶೇಷ ಪ್ರವೇಶದ ಅಗತ್ಯವಿಲ್ಲ."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ನೀವು ಈ ಬಿಲ್ಟ್-ಇನ್-ಅಪ್ಲಿಕೇಶನ್ನ ಅಪ್ಡೇಟ್ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಿಕೊಳ್ಳಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಇದಕ್ಕೆ ಯಾವುದೇ ವಿಶೇಷ ಪ್ರವೇಶದ ಅಗತ್ಯವಿಲ್ಲ."</string>
+ <string name="install_failed" msgid="6579998651498970899">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ಸ್ಥಾಪಿಸುವಿಕೆಯಿಂದ ಪ್ಯಾಕೇಜ್ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ಪ್ಯಾಕೇಜ್ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಪ್ಯಾಕೇಜ್ ಜೊತೆಗೆ ಸಂಘರ್ಷವಾಗುತ್ತದೆ."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ಅಪ್ಲಿಕೇಶನ್ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟಿವಿ ಜೊತೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ಅಪ್ಲಿಕೇಶನ್ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಫೋನ್ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ಪ್ಯಾಕೇಜ್ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಅಮಾನ್ಯವಾಗಿರುವಂತೆ ತೋರುತ್ತದೆ."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ನಿಮ್ಮ ಟಿವಿಗೆ ಸ್ಥಾಪಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
+ <string name="launch" msgid="4826921505917605463">"ತೆರೆ"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಪರಿಚಿತ ಮೂಲಗಳ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಸ್ಥಾಪನೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ಈ ಬಳಕೆದಾರರು ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಈ ಬಳಕೆದಾರರನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+ <string name="ok" msgid="3468756155452870475">"ಸರಿ"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ಖಾಲಿ ಇಲ್ಲ"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಕೊಂಚ ಸ್ಥಳವನ್ನು ಖಾಲಿ ಮಾಡಿ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿಲ್ಲ"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ಸ್ಥಾಪಿಸಲಾಗಿರುವ ಅಪ್ಲಿಕೇಶನ್ಗಳ ಪಟ್ಟಿಯಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿಲ್ಲ."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ಈ ಅಸ್ಥಾಪಿಸುವಿಕೆಯನ್ನು ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರಿಗೆ ನಿರ್ವಹಿಸಲು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ದೋಷ"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ಅಪ್ಲಿಕೇಶನ್ ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"ನವೀಕರಣವನ್ನು ಅನ್ಇನ್ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ಎಂಬುದು ಕೆಳಗಿನ ಅಪ್ಲಿಕೇಶನ್ನ ಭಾಗವಾಗಿದೆ:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ನೀವು "<b>"ಎಲ್ಲಾ"</b>" ಬಳಕೆದಾರರಿಗೂ ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಸಾಧನದಲ್ಲಿನ "<b>"ಎಲ್ಲಾ"</b>" ಬಳಕೆದಾರರಿಂದ ಅಪ್ಲಿಕೇಶನ್ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ತೆಗೆದುಹಾಕಲಾಗುವುದು."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> ಬಳಕೆದಾರರಿಗೆ ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ನೀವು ಬಯಸುವಿರಾ?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್ಗಳನ್ನು ಹೊಂದಿರುವವುಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ಈ ಸಾಧನದ ಎಲ್ಲಾ ಬಳಕೆದಾರರಿಗೆ ಇದು ಪರಿಣಾಮ ಬೀರುತ್ತದೆ."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ಚಾಲನೆಯಲ್ಲಿರುವ ಅಸ್ಥಾಪನೆಗಳು"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ವಿಫಲಗೊಂಡ ಅಸ್ಥಾಪನೆಗಳು"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"ಅಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"ಅನ್ಇನ್ಸ್ಟಾಲ್ ಪೂರ್ಣಗೊಂಡಿದೆ."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅಸ್ಥಾಪಿಸಲಾಗಿದೆ"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ಅನ್ಇನ್ಸ್ಟಾಲ್ ವಿಫಲವಾಗಿದೆ."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅಸ್ಥಾಪಿಸುವಿಕೆ ಯಶಸ್ವಿಯಾಗಲಿಲ್ಲ."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ಸಕ್ರಿಯ ಸಾಧನ ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> ಗಾಗಿ ಸಕ್ರಿಯ ಸಾಧನ ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ಕೆಲವು ಬಳಕೆದಾರರು ಅಥವಾ ಪ್ರೊಫೈಲ್ಗಳಿಗೆ ಈ ಅಪ್ಲಿಕೇಶನ್ ಅಗತ್ಯವಿರುತ್ತದೆ ಮತ್ತು ಇತರರಿಗೆ ಅಸ್ಥಾಪಿಸಲಾಗಿದೆ"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ಈ ಅಪ್ಲಿಕೇಶನ್ಗೆ ನಿಮ್ಮ ಪ್ರೊಫೈಲ್ನ ಅಗತ್ಯವಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಸಾಧನ ನಿರ್ವಾಹಕರಿಗೆ ಅಗತ್ಯವಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ಸಾಧನದ ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ಪ್ಯಾಕೇಜ್ ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ಸಮಸ್ಯೆ ಕಂಡುಬಂದಿದೆ."</string>
+ <string name="newPerms" msgid="6039428254474104210">"ಹೊಸತು"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ಎಲ್ಲಾ"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ಗೌಪ್ಯತೆ"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ಸಾಧನ ಪ್ರವೇಶ"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ಈ ನವೀಕರಣಕ್ಕೆ ಯಾವುದೇ ಹೊಸ ಅನುಮತಿಗಳ ಅಗತ್ಯವಿಲ್ಲ."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ನಿರಾಕರಿಸಿ"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿ"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ಹೇಗಾದರೂ ನಿರಾಕರಿಸಿ"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> ರಲ್ಲಿ <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<xliff:g id="ACTION">%2$s</xliff:g> <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> to <xliff:g id="ACTION">%2$s</xliff:g> ಅನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸುವುದೇ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ಅಪ್ಲಿಕೇಶನ್ ಬಳಸುವಾಗ ಮಾತ್ರ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ಯಾವಾಗಲೂ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ನಿರಾಕರಿಸಿ ಹಾಗೂ ಮತ್ತೊಮ್ಮೆ ಕೇಳಬೇಡ"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"ಎಲ್ಲಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ಯಾವುದನ್ನೂ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿಲ್ಲ"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ಅನುಮತಿಸಿ"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ಅಪ್ಲಿಕೇಶನ್ಗಳು"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಗಳು"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ಯಾವುದೇ ಅನುಮತಿಗಳಿಲ್ಲ"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"ಹೆಚ್ಚುವರಿ ಅನುಮತಿಗಳು"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿಯನ್ನು ತೆರೆಯಿರಿ"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಇನ್ನಷ್ಟು</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಇನ್ನಷ್ಟು</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ಈ ಅಪ್ಲಿಕೇಶನ್ Android ನ ಹಳೆಯ ಆವೃತ್ತಿಗೆ ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿತ್ತು. ಅನುಮತಿ ನಿರಾಕರಿಸುವಿಕೆ ಇನ್ನು ಮುಂದೆ ಉದ್ದೇಶಿಸಲ್ಪಟ್ಟಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸದೆ ಇರುವುದಕ್ಕೆ ಇದು ಕಾರಣವಾಗಬಹುದು."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ಅಪರಿಚಿತ ಕ್ರಿಯೆಯನ್ನು ಮಾಡಿ"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="COUNT_0">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"ಸಿಸ್ಟಂ ತೋರಿಸು"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"ಸಿಸ್ಟಂ ಮರೆಮಾಡು"</string>
+ <string name="no_apps" msgid="1965493419005012569">"ಅಪ್ಲಿಕೇಶನ್ಗಳು ಇಲ್ಲ"</string>
+ <string name="location_settings" msgid="1774875730854491297">"ಸ್ಥಳ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್ ಈ ಸಾಧನಕ್ಕೆ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ. ಸ್ಥಳ ಪ್ರವೇಶವನ್ನು ಸ್ಥಳ ಸೆಟ್ಟಿಂಗ್ಗಳಿಂದ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
+ <string name="system_warning" msgid="7103819124542305179">"ನೀವು ಈ ಅನುಮತಿಯನ್ನು ನಿರಾಕರಿಸಿದರೆ, ಇನ್ನು ಮುಂದೆ ನಿಮ್ಮ ಸಾಧನದ ಮೂಲ ವೈಶಿಷ್ಟ್ಯಗಳು ಉದ್ದೇಶಿದಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರಬಹುದು."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ನೀತಿಯ ಮೂಲಕ ಜಾರಿಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ನೀತಿಯ ಮೂಲಕ ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ನೀತಿ ಮೂಲಕ ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾದ"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ನೀತಿ ಮೂಲಕ ಮುನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾದ"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ಯಾವಾಗಲೂ"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ಅಪ್ಲಿಕೇಶನ್ ಬಳಸುವಾಗ ಮಾತ್ರ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ಎಂದೂ ಇಲ್ಲ"</string>
+ <string name="loading" msgid="7811651799620593731">"ಲೋಡ್ ಆಗುತ್ತಿದೆ..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"ಎಲ್ಲ ಅನುಮತಿಗಳು"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"ಇತರ ಅಪ್ಲಿಕೇಶನ್ ಸಾಮರ್ಥ್ಯಗಳು"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"ಅನುಮತಿ ವಿನಂತಿ"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"ಪರದೆ ಆವರಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಪತ್ತೆಹಚ್ಚಲಾಗಿದೆ"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ಈ ಅನುಮತಿ ಸೆಟ್ಟಿಂಗ್ ಬದಲಾಯಿಸಲು, ನೀವು ಮೊದಲು ಸೆಟ್ಟಿಂಗ್ಗಳು > ಅಪ್ಲಿಕೇಶನ್ಗಳಿಂದ ಪರದೆ ಆವರಿಸಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಆಫ್ ಮಾಡಬೇಕು"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ನಲ್ಲಿ ಸ್ಥಾಪಿಸುವಿಕೆ/ಅಸ್ಥಾಪಿಸುವಿಕೆ ಕ್ರಿಯೆಗಳು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಗೆ ಪ್ರವೇಶಿಸಲು ಯಾವುದನ್ನು ಅನುಮತಿಸಬೇಕು ಎಂಬುದನ್ನು ಆರಿಸಿಕೊಳ್ಳಿ"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಅನ್ನು ಅಪ್ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್ಗೆ ಪ್ರವೇಶಿಸಲು ಯಾವುದನ್ನು ಅನುಮತಿಸಬೇಕು ಎಂಬುದನ್ನು ಆರಿಸಿಕೊಳ್ಳಿ."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"ರದ್ದುಮಾಡಿ"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ಮುಂದುವರಿಸು"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"ಹೊಸ ಅನುಮತಿಗಳು"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"ಪ್ರಸ್ತುತ ಅನುಮತಿಗಳು"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ಸ್ಥಾಪಿಸಲು ಸಿದ್ಧವಿರುವ ಅಪ್ಲಿಕೇಶನ್…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"ಅಪರಿಚಿತ"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಈ ಮೂಲದಿಂದ ಬಂದಿರುವ ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ಗೆ ಅನುಮತಿಯಿಲ್ಲ."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಅಪರಿಚಿತ ಮೂಲಗಳಿಂದ ಪಡೆದುಕೊಳ್ಳುವ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನಿಮ್ಮ ಟಿವಿಯು ಸ್ಥಾಪಿಸದಂತೆ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಈ ಮೂಲದಿಂದ ಬಂದಿರುವ ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ನಿಮ್ಮ ಫೋನ್ಗೆ ಅನುಮತಿಯಿಲ್ಲ."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ನಿಮ್ಮ ಫೋನ್ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ, ನಿಮ್ಮ ಫೋನ್ಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ, ನಿಮ್ಮ ಫೋನ್ಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ನಿಮ್ಮ ಟಿವಿ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ, ನಿಮ್ಮ ಟಿವಿಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ಮುಂದುವರಿಸಿ"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"wear ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ/ಅಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ko-television/strings.xml b/packages/PackageInstaller/res/values-ko-television/strings.xml
new file mode 100644
index 0000000..6ad2ed6
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ko-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"거부 및 다시 묻지 않음"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"설정 > 앱에서 나중에 변경할 수 있습니다."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>개 중 <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"시스템 앱 보기"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"앱 권한"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"앱 권한"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> 권한"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"추가 권한"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> 권한"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ko-watch/strings.xml b/packages/PackageInstaller/res/values-ko-watch/strings.xml
new file mode 100644
index 0000000..6cce6f9
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ko-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"거부 및 다시 묻지 않음"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"시스템 앱 보기"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"변경할 수 없음"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"예"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"취소"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml
new file mode 100644
index 0000000..235a1d4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ko/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"패키지 설치 프로그램"</string>
+ <string name="next" msgid="3057143178373252333">"다음"</string>
+ <string name="install" msgid="5896438203900042068">"설치"</string>
+ <string name="done" msgid="3889387558374211719">"완료"</string>
+ <string name="cancel" msgid="8360346460165114585">"취소"</string>
+ <string name="installing" msgid="8613631001631998372">"설치 중..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 설치 중…"</string>
+ <string name="install_done" msgid="3682715442154357097">"앱이 설치되었습니다."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"이 애플리케이션을 설치하시겠습니까? 애플리케이션이 다음에 액세스할 수 있습니다."</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"이 애플리케이션을 설치하시겠습니까? 특별한 액세스 권한이 필요하지 않습니다."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"기존 애플리케이션에 업데이트를 설치하시겠습니까? 기존 데이터는 손실되지 않습니다. 업데이트된 애플리케이션이 다음에 액세스할 수 있습니다."</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"내장 애플리케이션에 업데이트를 설치하시겠습니까? 기존 데이터는 손실되지 않습니다. 업데이트된 애플리케이션이 다음에 액세스할 수 있습니다."</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"기존의 애플리케이션 업데이트를 설치하시겠습니까? 기존의 데이터는 손실되지 않으며 특별한 액세스 권한이 필요하지 않습니다."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"내장 애플리케이션 업데이트를 설치하시겠습니까? 기존의 데이터는 손실되지 않으며 특별한 액세스 권한이 필요하지 않습니다."</string>
+ <string name="install_failed" msgid="6579998651498970899">"앱이 설치되지 않았습니다."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"패키지 설치가 차단되었습니다."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"패키지가 기존 패키지와 충돌하여 앱이 설치되지 않았습니다."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"앱이 태블릿과 호환되지 않아서 설치되지 않았습니다."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"앱이 사용 중인 TV와 호환되지 않습니다."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"앱이 휴대전화와 호환되지 않아서 설치되지 않았습니다."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"패키지가 잘못되어 앱이 설치되지 않았습니다."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"태블릿에 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>을(를) TV에 설치할 수 없습니다."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"휴대전화에 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다."</string>
+ <string name="launch" msgid="4826921505917605463">"열기"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"관리자가 알 수 없는 출처의 앱 설치를 허용하지 않습니다."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"이 사용자는 알 수 없는 앱을 설치할 수 없습니다."</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"이 사용자는 앱을 설치할 권한이 없습니다."</string>
+ <string name="ok" msgid="3468756155452870475">"확인"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"앱 관리"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"여유 공간이 없음"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다. 여유 공간을 늘린 후에 다시 시도하세요."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"앱을 찾을 수 없음"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"설치된 앱 목록에 앱이 없습니다."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"허용되지 않음"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"현재 사용자는 이 제거를 수행할 수 없습니다."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"오류"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"앱을 제거할 수 없습니다."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"앱 제거"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"업데이트 제거"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>은(는) 다음 앱의 일부입니다."</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"이 앱을 제거하시겠습니까?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222"><b>"모든"</b>" 사용자에 대해 이 앱을 제거하시겠습니까? 기기를 사용하는 "<b>"모든"</b>" 사용자에 대해 애플리케이션 및 데이터가 삭제됩니다."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g>님의 기기에 설치된 앱을 제거하시겠습니까?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"이 앱을 초기 버전으로 바꾸시겠습니까? 모든 데이터가 삭제됩니다."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"이 앱을 초기 버전으로 바꾸시겠습니까? 모든 데이터가 삭제되며 직장 프로필 사용자를 포함해 이 기기의 모든 사용자에게 영향을 미칩니다."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"실행 중인 제거 작업"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"실패한 제거 작업"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"제거 중..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 제거 중…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"제거를 완료했습니다."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>을(를) 제거했습니다."</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"제거하지 못했습니다."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>을(를) 제거하지 못했습니다."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"활성 상태의 기기 관리자 앱을 제거할 수 없습니다."</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>의 활성 상태의 기기 관리자 앱을 제거할 수 없습니다."</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"이 앱은 일부 사용자 또는 프로필에 필요하며 다른 사용자에 대해서는 제거되었습니다."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"이 앱은 프로필에 필요하므로 삭제할 수 없습니다."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"이 앱은 기기 관리자에게 필요하므로 제거할 수 없습니다."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"기기 관리자 앱 관리"</string>
+ <string name="manage_users" msgid="3125018886835668847">"사용자 관리"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 제거할 수 없습니다."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"패키지를 파싱하는 중 문제가 발생했습니다."</string>
+ <string name="newPerms" msgid="6039428254474104210">"새 권한"</string>
+ <string name="allPerms" msgid="1024385515840703981">"전체"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"개인정보 보호"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"기기 액세스"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"이 업데이트에는 새로운 권한이 필요하지 않습니다."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"거부"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"추가 정보"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"거부"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>의 다음 작업을 허용하시겠습니까? <xliff:g id="ACTION">%2$s</xliff:g>"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>에서 <xliff:g id="ACTION">%2$s</xliff:g>하도록 허용하시겠습니까??"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"앱 사용 중에만"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"항상"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"거부 및 다시 묻지 않음"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>개 중지됨"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"모두 중지됨"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"아무것도 중지되지 않음"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"허용"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"앱"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"앱 권한"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"다시 묻지 않음"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"권한이 없음"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"추가 권한"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"앱 정보 열기"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 더보기</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 더보기</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"이 앱은 Android 이전 버전에 맞게 설계되었습니다. 권한을 거부하면 정상적으로 작동하지 않을 수 있습니다."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"알 수 없는 작업 수행"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>개 앱 허용됨"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"시스템 표시"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"시스템 숨기기"</string>
+ <string name="no_apps" msgid="1965493419005012569">"앱 없음"</string>
+ <string name="location_settings" msgid="1774875730854491297">"위치 설정"</string>
+ <string name="location_warning" msgid="8778701356292735971">"이 기기의 위치 서비스 제공업체는 <xliff:g id="APP_NAME">%1$s</xliff:g>입니다. 위치 정보 액세스는 위치 설정에서 수정할 수 있습니다."</string>
+ <string name="system_warning" msgid="7103819124542305179">"이 권한을 거부하는 경우 기기의 기본 기능이 제대로 작동하지 않을 수 있습니다."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"정책에 의해 시행됨"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"정책에 따라 백그라운드 액세스 사용 중지됨"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"정책에 따라 백그라운드 액세스 사용 설정함"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"정책에 따라 포그라운드 액세스 사용 설정함"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"관리자가 제어"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"항상"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"앱 사용 중에만"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"사용 안함"</string>
+ <string name="loading" msgid="7811651799620593731">"로드 중..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"모든 권한"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"다른 앱 기능"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"권한 요청"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"화면 오버레이 감지됨"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"이 권한 설정을 변경하려면 먼저 설정 > 앱에서 화면 오버레이를 사용하지 않도록 설정해야 합니다."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"설정 열기"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear에서 지원하지 않는 설치/제거 작업입니다."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>에서 액세스하도록 허용할 항목을 선택하세요."</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>이(가) 업데이트되었습니다. 이 앱에서 액세스하도록 허용할 항목을 선택하세요."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"취소"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"계속"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"새로운 권한"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"기존 권한"</string>
+ <string name="message_staging" msgid="6151794817691100003">"앱 준비 중…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"알 수 없음"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"보안상의 이유로 이 경로를 통한 알 수 없는 앱을 태블릿에 설치할 수 없습니다."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"보안상의 이유로 이 경로를 통한 알 수 없는 앱을 TV에 설치할 수 없습니다."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"보안상의 이유로 이 경로를 통한 알 수 없는 앱을 휴대전화에 설치할 수 없습니다."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"휴대전화와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 휴대전화 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"태블릿과 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 태블릿 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 TV 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"계속"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"설정"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear 앱 설치/제거"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ky-television/strings.xml b/packages/PackageInstaller/res/values-ky-television/strings.xml
new file mode 100644
index 0000000..20994ff
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ky-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Баш тартам жана экинчи суралбасын"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Муну кийин Жөндөөлөр > Колдонмолордон өзгөртө аласыз"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Тутум колдонмолорун көрсөтүү"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Колдонмонун уруксаттары"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Колдонмонун уруксаттары"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> уруксаттары"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Кошумча уруксаттар"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> уруксаттары"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ky-watch/strings.xml b/packages/PackageInstaller/res/values-ky-watch/strings.xml
new file mode 100644
index 0000000..aadb7c4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ky-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Баш тарам, экинчи суралбасын"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Тутум колдонмолорун көрсөтүү"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Өзгөртүүгө болбойт"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ооба"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Жокко чыгаруу"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
new file mode 100644
index 0000000..9a95c54
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Топтом орноткуч"</string>
+ <string name="next" msgid="3057143178373252333">"Кийинки"</string>
+ <string name="install" msgid="5896438203900042068">"Орнотуу"</string>
+ <string name="done" msgid="3889387558374211719">"Даяр"</string>
+ <string name="cancel" msgid="8360346460165114585">"Жокко чыгаруу"</string>
+ <string name="installing" msgid="8613631001631998372">"Орнотулууда…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> орнотулууда…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Колдонмо орнотулду."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Бул колдонмону орнотоюн дегениңиз аныкпы? Ал кийинкилерге жетки алат:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Бул колдонмону орнотоюн дегениңиз аныкпы? Ал эч бир атайын жетки уруксаттарын талап кылбайт."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Учурда иштеп турган бул колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Жаңыртылган колдонмо кийинкилерге жетки алат:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Бул камтылган колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Жаңыртылган колдонмо кийинкилерге жетки алат:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Учурда иштпе турган бул колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Ал эч бир атайын жетки уруксаттарын талап кылбайт."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Бул камтылган колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Ал эч бир атайын жетки уруксаттарын талап кылбайт."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Колдонмо орнотулган жок."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Топтом орнотуудан бөгөттөлгөн."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Башка топтом менен дал келбегендиктен колдонмо орнотулган жок."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Бул колдонмо планшетиңизге шайкеш эмес болгондуктан колдонмо орнотулган жок."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Бул колдонмо сыналгыңызга шайкеш келбейт."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Бул колдонмо телефонуңузга шайкеш эмес болгондуктан колдонмо орнотулган жок."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Топтом катары орнотулбай калган колдонмо жараксыз окшойт."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун планшетиңизге орнотуу мүмкүн эмес."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> сыналгыңызга орнотулбай койду."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун телефонуңузга орнотуу мүмкүн эмес."</string>
+ <string name="launch" msgid="4826921505917605463">"Ачуу"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Администраторуңуз белгисиз булактардан алынган колдонмолордун орнотулушуна жол бербейт"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Бул колдонуучу белгисиз колдонмолорду орното албайт"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Бул колдонуучу колдонмолорду орното албайт"</string>
+ <string name="ok" msgid="3468756155452870475">"Жарайт"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Колдонмолорду башкаруу"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Бош орун жок"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун телефонуңузга орнотуу мүмкүн эмес. Орун бошотуп, кайталап орнотуп көрүңүз."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Колдонмо табылган жок"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Колдонмо орнотулган колдонмолор тизмегинен табылган жок."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Тыюу салынган"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Учурдагы колдонуучу колдонмону чыгарып сала албайт."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Ката"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Колдонмону чыгарып салуу мүмкүн болбой жатат."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Колдонмону чечип салуу"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Жаңыртууну чечип салуу"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> кийинки колдонмонун бөлүгү:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Бул колдонмону чечип салгыңыз келеби?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Бул колдонмо "<b>"бардык"</b>" колдонуучулардан алынып салынсынбы? Бул колдонмо жана анын берилиштери бул түзмөктүн "<b>"бардык"</b>" колдонуучуларынан алынат."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Бул колдонмону <xliff:g id="USERNAME">%1$s</xliff:g> колдонуучусу үчүн орнотуудан чыгаргыңыз келеби?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Бул колдонмонун баштапкы версиясы орнотулсунбу? Бардык дайындар өчүп калат."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Бул колдонмонун баштапкы версиясы орнотулсунбу? Түзмөктөгү бардык профилдердин, ошондой эле жумушчу профилдин дайындары өчүп калат."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Чыгарылып салынууда"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Чыгарылып салынбай калгандар"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Чыгарылып салынууда…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> колдонмосу чыгарылууда…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Чечилип бүттү."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> колдонмосу чыгарылды"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Чечүү ийгиликсиз болду."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> колдонмосун чыгарып салуу ишке ашкан жок."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Түзмөктү башкарган колдонмо иштеп жатканда аны чыгарып салууга болбойт"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> колдонуучусунун түзмөктү башкарган колдонмосу иштеп жатканда, аны чыгарып салууга болбойт"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Колдонмо айрым колдонуучулар же профилдерге керек."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Бул колдонмо профилиңизге керек жана аны чыгарып салуу мүмкүн эмес."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Бул колдонмо түзмөк администраторуңузга керектелет жана орнотуудан чыгаруу мүмкүн эмес."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Түзмөктү башкарган колдонмолорду көзөмөлдөө"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Колдонуучуларды башкаруу"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун чечип салуу мүмкүн эмес."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Таңгакты окууда маселе пайда болду."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Жаңы"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Бардыгы"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Купуялуулук"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Жетүү уруксаттары"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Бул жаңыртуу жаңы уруксаттарды талап кылбайт."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Жок"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Көбүрөөк маалымат"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Баш тартуу"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> ичинен <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосуна <xliff:g id="ACTION">%2$s</xliff:g> уруксат берилсинби?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосуна <xliff:g id="ACTION">%2$s</xliff:g> аракетине ар дайым уруксат берилсинби?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Ушул колдонмодо иштегенде гана"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Ар дайым"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Баш тартам жана экинчи суралбасын"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> өчүрүлгөн"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"баары өчүрүлгөн"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"эч бири өчүрүлгөн жок"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Уруксат берүү"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Колдонмолор"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Колдонмо уруксаттары"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Экинчи суралбасын"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Уруксаттар жок"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Кошумча уруксаттар"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Колдонмо тууралуу маалыматты ачуу"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Дагы <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Дагы <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Бул колдонмо эски Android версиясы үчүн түзүлгөн. Уруксат берилбесе, ал туура эмес иштеп калышы мүмкүн."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"белгисиз аракеттерди жасайт"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> колдонмонун ичинен <xliff:g id="COUNT_0">%1$d</xliff:g> уруксат берилген"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Тутумду көрсөтүү"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Тутумдагы процесстерди жашыруу"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Бир дагы колдонмо жок"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Геолокация параметрлери"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> - бул түзмөктөгү жайгашкан жерди аныктоо кызматынын камсыздоочусу. Жайгашкан жерди көрүү мүмкүнчүлүгүн жайгашкан жерди аныктоо жөндөөлөрүнөн өзгөртсө болот."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Эгер бул уруксатты четке каксаңыз, түзмөгүңүздүн негизги функциялары талаптагыдай иштебей калышы мүмкүн."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Саясат тарабынан күчүнө киргизилген"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Фондук режимде колдонуу саясат тарабынан өчүрүлгөн"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Фондук режимде колдонуу саясат тарабынан иштетилген"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Активдүү режим саясат боюнча иштетилген"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Администратор тарабынан көзөмөлдөнөт"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Ар дайым"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Ушул колдонмодо иштегенде гана"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Эч качан"</string>
+ <string name="loading" msgid="7811651799620593731">"Жүктөлүүдө…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Бардык уруксаттар"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Колдонмонун башка жөндөмдөрү"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Уруксат суроо"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Экран кабатталышы аныкталды"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Бул уруксаттын жөндөөсүн өзгөртүү үчүн, адегенде Жөндөөлөр > Колдонмолордон экрандын кабатталышын өчүрүңүз"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Жөндөөлөрдү ачуу"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Тагынма"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Орнотуу/чыгарып салуу аракеттери Android Wear\'де колдоого алынбайт."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> колдонмосу үчүн уруксаттарды тандаңыз"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> жаңыртылды. Ал үчүн уруксаттарды тандаңыз."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Жок"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Улантуу"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Жаңы уруксаттар"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Учурдагы уруксаттар"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Күтө туруңуз…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Белгисиз"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Коопсуздукту сактоо максатында, планшетиңизге бул булактан колдонмолорду орнотууга уруксат жок."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Коопсуздукту сактоо максатында, сыналгыңызга бул булактан колдонмолорду орнотууга уруксат жок."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Коопсуздукту сактоо максатында, телефонуңузга бул булактан колдонмолорду орнотууга уруксат жок."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефонуңуз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам телефонуңузга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Планшетиңиз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам TV\'ңизге кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Улантуу"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Жөндөөлөр"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Тагынма колдонмолорду орнотуу/чыгаруу"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lo-television/strings.xml b/packages/PackageInstaller/res/values-lo-television/strings.xml
new file mode 100644
index 0000000..a6f4e49
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lo-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"ປະຕິເສດ ແລະຢ່າຖາມອີກ"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ທ່ານສາມາດປ່ຽນແປງສິ່ງນີ້ໃນພາຍຫຼັງໄດ້ໃນການຕັ້ງຄ່າ > ແອັບ"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"ສະແດງແອັບລະບົບ"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ການອະນຸຍາດແອັບ"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ການອະນຸຍາດແອັບ"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> ການອະນຸຍາດ"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"ການອະນຸຍາດເພີ່ມເຕີມ"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> ການອະນຸຍາດ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lo-watch/strings.xml b/packages/PackageInstaller/res/values-lo-watch/strings.xml
new file mode 100644
index 0000000..4fae329
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lo-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ປະຕິເສດ, ຢ່າຖາມອີກ"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"ສະແດງແອັບລະບົບ"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ບໍ່ສາມາດປ່ຽນແປງໄດ້"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ແມ່ນແລ້ວ"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"ຍົກເລີກ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml
new file mode 100644
index 0000000..f39f140
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lo/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"ໂຕຕິດຕັ້ງແພັກເກດ"</string>
+ <string name="next" msgid="3057143178373252333">"ຕໍ່ໄປ"</string>
+ <string name="install" msgid="5896438203900042068">"ຕິດຕັ້ງ"</string>
+ <string name="done" msgid="3889387558374211719">"ແລ້ວໆ"</string>
+ <string name="cancel" msgid="8360346460165114585">"ຍົກເລີກ"</string>
+ <string name="installing" msgid="8613631001631998372">"ກຳລັງຕິດຕັ້ງ…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"ກຳລັງຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ຕິດຕັ້ງແອັບຯແລ້ວ."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ທ່ານຕ້ອງການຕິດຕັ້ງແອັບພລິເຄຊັນນີ້ບໍ່? ມັນຈະໄດ້ສິດການເຂົ້າເຖິງ:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ທ່ານຕ້ອງການຕິດຕັ້ງແອັບພລິເຄຊັນນີ້ບໍ່? ມັນບໍ່ຕ້ອງໃຊ້ສິດທິການເຂົ້າເຖິງພິເສດໃດໆ."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດໃສ່ແອັບພລິເຄຊັນນີ້ບໍ່? ຂໍ້ມູນຂອງທ່ານທີ່ມີຢູ່ກ່ອນແລ້ວຈະຍັງຄົງຢູ່ຄືເກົ່າ. ແອັບພລິເຄຊັນທີ່ຜ່ານການອັບເດດຈະສາມາດເຂົ້າເຖິງ:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ທ່ານຕ້ອງການທີ່ຈະຕິດຕັ້ງຊຸດອັບເດດສຳລັບແອັບຯນີ້ບໍ່? ຂໍ້ມູນທີ່ທ່ານມີຢູ່ຈະບໍ່ສູນຫາຍ. ການອັບເດດແອັບພລິເຄຊັນນີ້ຈະສາມາດເຂົ້າເຖິງ:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດໃສ່ແອັບພລິເຄຊັນນີ້ບໍ່? ຂໍ້ມູນຂອງທ່ານທີ່ມີຢູ່ກ່ອນແລ້ວຈະຍັງຄົງຢູ່ຄືເກົ່າ. ມັນບໍ່ຕ້ອງການສິດເຂົ້າເຖິງພິເສດໃດໆ."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດໃສ່ແອັບພລິເຄຊັນທີ່ມີມານຳນີ້ບໍ່? ຂໍ້ມູນຂອງທ່ານທີ່ມີຢູ່ກ່ອນແລ້ວຈະຍັງຄົງຢູ່ຄືເກົ່າ. ມັນບໍ່ຕ້ອງການສິດເຂົ້າເຖິງພິເສດໃດໆເລີຍ."</string>
+ <string name="install_failed" msgid="6579998651498970899">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບຯເທື່ອ."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ແພັກເກດຖືກບລັອກບໍ່ໃຫ້ໄດ້ຮັບການຕິດຕັ້ງ"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ແອັບນີ້ບໍ່ເຂົ້າກັນໄດ້ກັບໂທລະພາບຂອງທ່ານ."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ໃສ່ແທັບເລັດຂອງທ່ານໄດ້."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ສາມາດຕິດຕັ້ງໃສ່ໂທລະພາບຂອງທ່ານໄດ້."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ໃນໂທລະສັບຂອງທ່ານໄດ້."</string>
+ <string name="launch" msgid="4826921505917605463">"ເປີດ"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ຕິດຕັ້ງແອັບທີ່ໄດ້ມາຈາກແຫຼ່ງທີ່ບໍ່ຮູ້ຈັກ"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ຜູ້ໃຊ້ນີ້ບໍ່ສາມາດຕິດຕັ້ງແອັບທີ່ບໍ່ຮູ້ຈັກໄດ້"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ຜູ້ໃຊ້ນີ້ບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ຕິດຕັ້ງແອັບໄດ້"</string>
+ <string name="ok" msgid="3468756155452870475">"ຕົກລົງ"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"ຈັດການແອັບຯ"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ພື້ນທີ່ຫວ່າງບໍ່ພຽງພໍ"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ໄດ້. ກະລຸນາລຶບຂໍ້ມູນທີ່ບໍ່ຈຳເປັນອອກ ເພື່ອໃຫ້ມີບ່ອນຈັດເກັບຂໍ້ມູນຫວ່າງເພີ່ມຂຶ້ນ ແລ້ວລອງໃໝ່ອີກຄັ້ງ."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ບໍ່ພົບເຫັນແອັບຯ"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ບໍ່ພົບແອັບຯໃນລາຍການຂອງແອັບຯທີ່ຕິດຕັ້ງແລ້ວ."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ບໍ່ອະນຸຍາດແລ້ວ"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ຜູ້ໃຊ້ປັດຈຸບັນບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ຖອນການຕິດຕັ້ງນີ້ໄດ້."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ຜິດພາດ"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ບໍ່ສາມາດຖອນການຕິດຕັ້ງແອັບໄດ້."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ຖອນການຕິດຕັ້ງແອັບຯ"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"ຖອນການຕິດຕັ້ງອັບເດດ"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ແມ່ນສ່ວນນຶ່ງຂອງແອັບຯຂ້າງລຸ່ມ:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ທ່ານຕ້ອງການຖອນການຕິດຕັ້ງແອັບຯນີ້ບໍ່?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ທ່ານຕ້ອງການທີ່ຈະຖອນການຕິດຕັ້ງແອັບຯນີ້ ສຳລັງຜູ່ໃຊ້"<b>"ທຸກຄົນ"</b>"ບໍ່? ແອັບພລິເຄຊັນ ແລະຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ ຈາກຜູ່ໃຊ້"<b>"ທັງໝົດ"</b>"ໃນອຸປະກອນນີ້."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"ທ່ານຕ້ອງການຖອນການຕິດຕັ້ງແອັບຯນີ້ສຳລັບຜູ່ໃຊ້ <xliff:g id="USERNAME">%1$s</xliff:g> ບໍ່?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ແທນທີ່ແອັບນີ້ດ້ວຍເວີຊັນທີ່ມາຈາກໂຮງງານບໍ? ຂໍ້ມູນທັງໝົດຈະຖືກລຶບອອກ."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ແທນທີ່ແອັບນີ້ດ້ວຍເວີຊັນທີ່ມາຈາກໂຮງງານບໍ? ຂໍ້ມູນທັງໝົດຈະຖືກລຶບອອກ ເຊິ່ງມີຜົນກັບຜູ້ໃຊ້ອຸປະກອນນີ້ທຸກຄົນ ຮວມທັງຄົນທີ່ມີໂປຣໄຟລ໌ບ່ອນເຮັດວຽກນຳ."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ກຳລັງຖອນການຕິດຕັ້ງ"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ຖອນການຕິດຕັ້ງບໍ່ສຳເລັດ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"ກຳລັງຖອນການຕິດຕັ້ງ..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"ກຳລັງຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"ຖອນການຕິດຕັ້ງສຳເລັດແລ້ວ."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ແລ້ວ"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ການຖອນການຕິດຕັ້ງບໍ່ສຳເລັດ."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ບໍ່ສຳເລັດ."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ບໍ່ສາມາດຖອນການຕິດຕັ້ງແອັບອຸປະກອນທີ່ເຮັດວຽກຢູ່ໄດ້"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"ບໍ່ສາມາດຖອນການຕິດຕັ້ງແອັບຜູ້ເບິ່ງແຍງລະບົບທີ່ເຮັດວຽກຢູ່ສຳລັບ <xliff:g id="USERNAME">%1$s</xliff:g> ໄດ້"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ແອັບນີ້ຈຳເປັນສຳລັບບາງຜູ້ໃຊ້ ຫຼື ບາງໂປຣໄຟລ໌ ແລະ ຖືກຖອນການຕິດຕັ້ງສຳລັບຄົນອື່ນແລ້ວ"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ແອັບນີ້ຈຳເປັນຕ້ອງໃຊ້ກັບໂປຣໄຟລ໌ຂອງທ່ານ ແລະ ບໍ່ສາມາດຖອນການຕິດຕັ້ງໄດ້."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ແອັບຯນີ້ຕ້ອງໃຊ້ໂດຍຜູ່ເບິ່ງແຍງລະບົບຂອງທ່ານ ແລະບໍ່ສາມາດຖອນການຕິດຕັ້ງໄດ້."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ຈັດການແອັບຜູ້ເບິ່ງແຍງອຸປະກອນ"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ຈັດການຜູ້ໃຊ້"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ສາມາດຖອນອອກໄດ້."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ເກີດບັນຫາໃນການວິເຄາະແພັກເກດ."</string>
+ <string name="newPerms" msgid="6039428254474104210">"ໃໝ່"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ທັງໝົດ"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ຄວາມເປັນສ່ວນຕົວ"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ການເຂົ້າເຖິງອຸປະກອນ"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ອັບເດດນີ້ບໍ່ຕ້ອງການການອະນຸຍາດໃໝ່."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ປະຕິເສດ"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ຂໍ້ມູນເພີ່ມເຕີມ"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ຢືນຢັນປະຕິເສດ"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ໃນ <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"ອະນຸຍາດໃຫ້ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ສາມາດ <xliff:g id="ACTION">%2$s</xliff:g> ບໍ?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"ອະນຸຍາດ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ໃຫ້ໃຊ້ <xliff:g id="ACTION">%2$s</xliff:g> ໄດ້ທຸກເທື່ອບໍ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ໃນເວລາໃຊ້ແອັບເທົ່ານັ້ນ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ທຸກເທື່ອ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ປະຕິເສດ ແລະ ຢ່າຖາມອີກ"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"ປິດໄວ້ <xliff:g id="COUNT">%1$d</xliff:g> ສິດອະນຸຍາດແລ້ວ"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"ປິດໄວ້ທັງໝົດແລ້ວ"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ບໍ່ມີອັນໃດປິດການນຳໃຊ້ໄວ້"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ອະນຸຍາດ"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ແອັບ"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ການອະນຸຍາດແອັບ"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ບໍ່ຕ້ອງຖາມອີກ"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ບໍ່ມີການອະນຸຍາດ"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"ການອະນຸຍາດເພີ່ມເຕີມ"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ເປີດຂໍ້ມູນແອັບ"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ເພີ່ມເຕີມ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ເພີ່ມເຕີມ</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ແອັບນີ້ຖືກອອກແບບມາສຳລັບ Android ເວີຊັນເກົ່າ. ການປະຕິເສດການອະນຸຍາດອາດຈະເຮັດໃຫ້ມັນບໍ່ເຮັດວຽກຕາມຕ້ອງການໄດ້ອີກ."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ເຮັດການດຳເນີນການທີ່ບໍ່ຮູ້ຈັກ"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> ໃນ <xliff:g id="COUNT_1">%2$d</xliff:g> ແອັບໄດ້ຮັບອະນຸຍາດແລ້ວ"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"ສະແດງລະບົບ"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"ເຊື່ອງລະບົບ"</string>
+ <string name="no_apps" msgid="1965493419005012569">"ບໍ່ມີແອັບ"</string>
+ <string name="location_settings" msgid="1774875730854491297">"ການຕັ້ງຄ່າທີ່ຕັ້ງ"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນຜູ້ໃຫ້ບໍລິການເລື່ອງການບໍລິການທີ່ຕັ້ງສຳລັບອຸປະກອນນີ້. ການເຂົ້າເຖິງທີ່ຕັ້ງແມ່ນສາມາດດັດແປງໄດ້ຈາກການຕັ້ງຄ່າທີ່ຕັ້ງ."</string>
+ <string name="system_warning" msgid="7103819124542305179">"ຖ້າທ່ານປະຕິເສດການອະນຸຍາດນີ້, ຄຸນສົມບັດໃຊ້ງານພື້ນຖານຂອງອຸປະກອນຂອງທ່ານອາດຈະບໍ່ເຮັດໜ້າທີ່ຕາມທີ່ກຳນົດໄວ້."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ບັງຄັບໃຊ້ຕາມນະໂຍບາຍແລ້ວ"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ປິດນຳໃຊ້ການເຂົ້າເຖິງໃນພື້ນຫຼັງຕາມນະໂຍບາຍແລ້ວ"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ເປີດນຳໃຊ້ການເຂົ້າເຖິງໃນພື້ນຫຼັງຕາມນະໂຍບາຍແລ້ວ"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ເປີດນຳໃຊ້ການເຂົ້າເຖິງໃນພື້ນໜ້າຕາມນະໂຍບາຍແລ້ວ"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ທຸກເທື່ອ"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ໃນເວລາໃຊ້ແອັບເທົ່ານັ້ນ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ບໍ່ເລີຍ"</string>
+ <string name="loading" msgid="7811651799620593731">"ກຳລັງໂຫລດ..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"ທຸກການອະນຸຍາດ"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"ຄວາມສາມາດອື່ນຂອງແອັບ"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"ການຮ້ອງຂໍການອະນຸຍາດ"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"ກວດພົບການວາງຊ້ອນໜ້າຈໍແລ້ວ"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ເພື່ອປ່ຽນແປງການຕັ້ງຄ່າການອະນຸຍາດນີ້, ກ່ອນອື່ນໝົດທ່ານຕ້ອງປິດການວາງຊ້ອນໜ້າຈໍຈາກແອັບການຕັ້ງຄ່າ"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ເປີດການຕັ້ງຄ່າ"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ຕິດຕັ້ງ/ຖອນຕິດຕັ້ງ ຄຳສັ່ງທີ່ບໍ່ຮອງຮັບຢູ່ໃນ Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"ເລືອກວ່າຈະອະນຸຍາດໃຫ້ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ເຂົ້າເຖິງຫຍັງໄດ້ແດ່"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"ອັບເດດ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ແລ້ວ. ກະລຸນາເລືອກວ່າຈະໃຫ້ແອັບນີ້ເຂົ້າເຖິງຫຍັງໄດ້ແດ່."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"ຍົກເລີກ"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ສືບຕໍ່"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"ການອະນຸຍາດໃໝ່"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"ການອະນຸຍາດປັດຈຸບັນ"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ກຳລັງຮຽງແອັບ…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"ບໍ່ຮູ້ຈັກ"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ແທັບເລັດຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ໂທລະທັດຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ໂທລະສັບຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ໂທລະສັບ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ແທັບເລັດ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ໂທລະທັດ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ດຳເນີນການຕໍ່"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ການຕັ້ງຄ່າ"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"ກຳລັງຕິດຕັ້ງ/ຖອດຖອນແອັບ Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lt-television/strings.xml b/packages/PackageInstaller/res/values-lt-television/strings.xml
new file mode 100644
index 0000000..dee6de7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lt-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Atmesti ir daugiau neklausti"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Tai vėliau galėsite pakeisti skiltyje „Nustatymai > Programos“"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Rodyti sistemos programas"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Programos leidimai"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Programos leidimai"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> leidimai"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Papildomi leidimai"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> leidimai"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lt-watch/strings.xml b/packages/PackageInstaller/res/values-lt-watch/strings.xml
new file mode 100644
index 0000000..85eebcf
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lt-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Atmesti, daugiau neklausti"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Rodyti sistemos programas"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Negalima pakeisti"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Taip"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Atšaukti"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml
new file mode 100644
index 0000000..79546a9
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lt/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Paketo įdiegimo programa"</string>
+ <string name="next" msgid="3057143178373252333">"Kitas"</string>
+ <string name="install" msgid="5896438203900042068">"Įdiegti"</string>
+ <string name="done" msgid="3889387558374211719">"Atlikta"</string>
+ <string name="cancel" msgid="8360346460165114585">"Atšaukti"</string>
+ <string name="installing" msgid="8613631001631998372">"Diegiama..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Įdiegiama „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Programa įdiegta."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Ar norite įdiegti šią programą? Jai bus suteikta prieiga prie:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ar norite įdiegti šią programą? Jai nereikalinga jokia speciali prieiga."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Ar norite įdiegti šios esamos programos naujinį? Neprarasite esamų duomenų. Atnaujinus programą bus suteikta prieiga prie:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ar norite įdiegti šios integruotos programos naujinį? Neprarasite esamų duomenų. Atnaujinus programą bus suteikta prieiga prie:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ar norite įdiegti šios esamos programos naujinį? Neprarasite esamų duomenų. Nereikia jokios specialios prieigos."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ar norite įdiegti šios integruotos programos naujinį? Neprarasite esamų duomenų. Nereikia jokios specialios prieigos."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Programa neįdiegta."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paketas užblokuotas ir negali būti įdiegtas."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Programa neįdiegta, nes paketas nesuderinamas su esamu paketu."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Programa neįdiegta, nes ji nesuderinama su planšetiniu kompiuteriu."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ši programa nesuderinama su jūsų TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Programa neįdiegta, nes ji nesuderinama su telefonu."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Programa neįdiegta, nes panašu, kad paketas netinkamas."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Jūsų planšetiniame kompiuteryje nepavyko įdiegti „<xliff:g id="APP_NAME">%1$s</xliff:g>“."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nepavyko programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ įdiegti jūsų TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Jūsų telefone nepavyko įdiegti „<xliff:g id="APP_NAME">%1$s</xliff:g>“."</string>
+ <string name="launch" msgid="4826921505917605463">"Atidaryti"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Jūsų administratorius neleidžia diegti programų, gautų iš nežinomų šaltinių"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Šis naudotojas negali diegti nežinomų programų"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Šiam naudotojui neleidžiama diegti programų"</string>
+ <string name="ok" msgid="3468756155452870475">"Gerai"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Tvarkyti programas"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nėra vietos"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Nepavyko įdiegti „<xliff:g id="APP_NAME">%1$s</xliff:g>“. Atlaisvinkite vietos ir bandykite dar kartą."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Programa nerasta"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Programa nerasta įdiegtų programų sąraše."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Neleidžiama"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Dabartiniam naudotojui neleidžiama atlikti šio pašalinimo veiksmo."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Klaida"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nepavyko įdiegti programos."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Pašalinti programą"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Pašalinti naujinį"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"„<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>“ yra šios programos dalis:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Ar norite pašalinti šią programą?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ar norite pašalinti šią programą "<b>"visiems"</b>" naudotojams? Programa ir jos duomenys bus pašalinti iš "<b>"visų"</b>" naudotojų įrenginyje."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ar norite pašalinti šią naudotojo <xliff:g id="USERNAME">%1$s</xliff:g> programą?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti. Tai paveiks visus šio įrenginio naudotojus, įskaitant turinčius darbo profilius."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Vykdomi įdiegimai"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Nepavykę įdiegimai"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Pašalinama..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Pašalinama „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Pašalinimas baigtas."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Paketas „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalintas"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Nepavyko pašalinti."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"„<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalinimo veiksmas nesėkmingas."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Negalima pašalinti aktyvios įrenginio administravimo programos"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Negalima pašalinti aktyvios naudotojo <xliff:g id="USERNAME">%1$s</xliff:g> įrenginio administravimo programos"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ši programa reikalinga kai kuriems naudotojams ar kai kuriuose profiliuose ir buvo pašalinta kitur"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ši programa reikalinga jūsų profilyje ir jos negalima pašalinti."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ši programa reikalinga jūsų įrenginio administratoriui ir jos negalima pašalinti."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Tvarkyti įrenginio administravimo programas"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Valdyti naudotojus"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nepavyko pašalinti „<xliff:g id="APP_NAME">%1$s</xliff:g>“."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Analizuojant paketą iškilo problema."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Naujiena"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Visi"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privatumas"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Prieiga prie įreng."</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Šiam naujiniui nereikalingi nauji leidimai."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Atmesti"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Daugiau informacijos"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Vis tiek atmesti"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> iš <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Leisti programai <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Visada leisti programai <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Tik naudojant programą"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Visada"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Atmesti ir daugiau neklausti"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Išjungta leidimų: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"visi leidimai išjungti"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nė vienas leidimas neišjungtas"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Leisti"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Programos"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Programos leidimai"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Daugiau neklausti"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nėra jokių leidimų"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Papildomi leidimai"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Atidaryti programos informaciją"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ši programa skirta senesnės versijos „Android“. Uždraudus leidimą ji gali nebeveikti kaip numatyta."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"atlieka nežinomą veiksmą"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Leidžiama programų: <xliff:g id="COUNT_0">%1$d</xliff:g> iš <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Rodyti sistemą"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Slėpti sistemą"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nėra jokių programų"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Vietovės nustatymai"</string>
+ <string name="location_warning" msgid="8778701356292735971">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ yra šio įrenginio vietovės paslaugų teikėjas. Vietovės pasiekiamumą galima keisti vietovės nustatymuose."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Jei uždrausite šį leidimą, pagrindinės įrenginio funkcijos gali nebeveikti, kaip numatyta."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Reikalaujama pagal politikos nuostatas"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Prieiga fone išjungta pagal politiką"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Prieiga fone įgalinta pagal politiką"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Prieiga priekiniame plane įgalinta pagal politiką"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Valdo administratorius"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Visada"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Tik naudojant programą"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Niekada"</string>
+ <string name="loading" msgid="7811651799620593731">"Įkeliama..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Visi leidimai"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Kitos programos galimybės"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Leidimo užklausa"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Aptikta ekrano perdanga"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Jei norite pakeisti šį leidimo nustatymą, pirmiausia turite išjungti ekrano perdangą skiltyje „Nustatymai > Programos“"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Atidaryti nustatymus"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Diegimo / pašalinimo veiksmai nepalaikomi sistemoje „Wear“."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Pasirinkite, ką norite leisti programai <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> pasiekti"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Programa <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> buvo atnaujinta. Pasirinkite, ką norite leisti šiai programai pasiekti."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Atšaukti"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Tęsti"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nauji leidimai"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Dabartiniai leidimai"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Programa pateikiama etapais…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Nežinoma"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Saugos sumetimais planšetiniame kompiuteryje neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Saugos sumetimais TV neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Saugos sumetimais telefone neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonas ir asmeniniai duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą telefonui arba prarastus duomenis dėl šios programos naudojimo."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Planšetinis kompiuteris ir asmeniniai duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą planšetiniam kompiuteriui arba prarastus duomenis dėl šios programos naudojimo."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV ir asmeniniai duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą TV arba prarastus duomenis dėl šios programos naudojimo."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Tęsti"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Nustatymai"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Įdiegiamos / pašalinamos „Wear“ program."</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lv-television/strings.xml b/packages/PackageInstaller/res/values-lv-television/strings.xml
new file mode 100644
index 0000000..f01dfd2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lv-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Noraidīt un vairs nejautāt"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Vēlāk varat veikt izmaiņas sadaļā Iestatījumi > Lietotnes."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. no <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Rādīt sistēmas lietotnes"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Lietotņu atļaujas"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Lietotņu atļaujas"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Lietotnes <xliff:g id="PERMISSION">%1$s</xliff:g> atļaujas"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Papildu atļaujas"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Lietotnes <xliff:g id="PERMISSION">%1$s</xliff:g> atļaujas"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lv-watch/strings.xml b/packages/PackageInstaller/res/values-lv-watch/strings.xml
new file mode 100644
index 0000000..29aef48
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lv-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Neatļaut un vairs nejautāt"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. no <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Rādīt sistēmas lietotnes"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Nevar mainīt"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Jā"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Atcelt"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml
new file mode 100644
index 0000000..40ddf74
--- /dev/null
+++ b/packages/PackageInstaller/res/values-lv/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pakotnes instalēšanas programma"</string>
+ <string name="next" msgid="3057143178373252333">"Tālāk"</string>
+ <string name="install" msgid="5896438203900042068">"Instalēt"</string>
+ <string name="done" msgid="3889387558374211719">"Gatavs"</string>
+ <string name="cancel" msgid="8360346460165114585">"Atcelt"</string>
+ <string name="installing" msgid="8613631001631998372">"Notiek instalēšana..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Notiek pakotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> instalēšana…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Lietotne ir instalēta."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Vai vēlaties instalēt šo lietojumprogrammu? Tā iegūs piekļuvi:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vai vēlaties instalēt šo lietojumprogrammu? Tai nav nepieciešamas īpašas piekļuves atļaujas."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Vai vēlaties instalēt šīs lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Atjauninātajai lietojumprogrammai būs piekļuve:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vai vēlaties instalēt šīs iebūvētās lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Atjauninātajai lietojumprogrammai būs piekļuve:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vai vēlaties instalēt šīs lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Tam nav nepieciešama īpaša piekļuves atļauja."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vai vēlaties instalēt šīs iebūvētās lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Tam nav nepieciešama īpaša piekļuves atļauja."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Lietotne nav instalēta."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Pakotnes instalēšana tika bloķēta."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Lietotne netika instalēta, jo rodas pakotnes konflikts ar esošo pakotni."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Lietotne netika instalēta, jo tā nav saderīga ar jūsu planšetdatoru."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Šī lietotne nav saderīga ar jūsu televizoru."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Lietotne netika instalēta, jo tā nav saderīga ar jūsu tālruni."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Lietotne netika instalēta, jo šķiet, ka pakotne nav derīga."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt planšetdatorā."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt jūsu televizorā."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt tālrunī."</string>
+ <string name="launch" msgid="4826921505917605463">"Atvērt"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Jūsu administrators neļauj instalēt lietotnes, kas iegūtas no nezināmiem avotiem."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Šis lietotājs nevar instalēt lietotnes, kas iegūtas no nezināmiem avotiem."</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Šim lietotājam nav atļauts instalēt lietotnes"</string>
+ <string name="ok" msgid="3468756155452870475">"Labi"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Pārvaldīt lietotnes"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nav brīvas vietas"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt. Atbrīvojiet vietu un mēģiniet vēlreiz."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Lietotne nav atrasta"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Šī lietotne netika atrasta instalēto lietotņu sarakstā."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nav atļauts"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Pašreizējam lietotājam nav atļauts veikt atinstalēšanu."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Kļūda"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nevarēja atinstalēt lietotni."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Atinstalēt lietotni"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Atinstalēt atjauninājumu"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ir daļa no šādas lietotnes:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Vai vēlaties atinstalēt šo lietotni?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vai vēlaties atinstalēt šo lietotni "<b>"visiem"</b>" lietotājiem? Šī lietojumprogramma un tās dati tiks noņemti no "<b>"visiem"</b>" ierīces lietotāju kontiem."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vai vēlaties atinstalēt šo lietotni lietotājam <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti. Tas ietekmēs visu šīs ierīces lietotāju (arī to lietotāju, kuriem ir darba profili) datus."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Pašlaik veiktie atinstalēšanas gadījumi"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neizdevušies atinstalēšanas gadījumi"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Notiek atinstalēšana..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Notiek lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Atinstalēšana ir pabeigta."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Lietotne <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ir atinstalēta"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Atinstalēšana neizdevās."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana nebija sekmīga."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Neizdevās atinstalēt aktīvas ierīces administratora lietotnes."</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Neizdevās atinstalēt aktīvas ierīces administratora lietotni <xliff:g id="USERNAME">%1$s</xliff:g>."</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Šī lietotne ir nepieciešama dažiem lietotājiem vai profiliem un tika atinstalēta citiem"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Šī lietotne ir nepieciešama jūsu profilam, tāpēc to nevar atinstalēt."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ierīces administrators ir noteicis, ka lietotne ir obligāta un to nevar atinstalēt."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Pārvaldīt ierīces administratora lietotnes"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Pārvaldīt lietotājus"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja atinstalēt."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Parsējot pakotni, radās problēma."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Jauna!"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Visas"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Konfidencialitāte"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Piekļuve ierīcei"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Šim atjauninājumam nav nepieciešamas jaunas atļaujas."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Neatļaut"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Plašāka informācija"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tomēr noraidīt"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. no <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Vai atļaut lietotnei <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vai vienmēr atļaut lietotnei <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Tikai izmantojot lietotni"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Vienmēr"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Noraidīt un vairs nejautāt"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> atspējotas"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"visas atspējotas"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"neviena nav atspējota"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Atļaut"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Lietotnes"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Lietotnes atļaujas"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Turpmāk vairs nejautāt"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nav atļauju"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Papildu atļaujas"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Atvērt lietotnes informāciju"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="zero">Vēl <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Vēl <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Vēl <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Šī lietotne ir paredzēta vecākai Android versijai. Ja noraidīsiet atļauju, iespējams, netiks nodrošināta paredzētā lietotnes darbība."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"veikt nezināmu darbību"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Atļautas <xliff:g id="COUNT_0">%1$d</xliff:g> lietotnes no <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Rādīt sistēmas lietotnes"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Slēpt sistēmas lietotnes"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nav lietotņu"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Atrašanās vietas iestatījumi"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> nodrošina šai ierīcei atrašanās vietu pakalpojumus. Piekļuves iestatījumus atrašanās vietas datiem var mainīt atrašanās vietas iestatījumos."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ja nepiešķirsiet šo atļauju, ierīces pamatfunkcijas, iespējams, vairs nedarbosies, kā paredzēts."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Īstenota saskaņā ar politiku"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Piekļuve fonā atspējota saskaņā ar politiku"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Piekļuve fonā iespējota saskaņā ar politiku"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Piekļuve priekšplānā iespējota saskaņā ar politiku"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolē administrators"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Vienmēr"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Tikai izmantojot lietotni"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nekad"</string>
+ <string name="loading" msgid="7811651799620593731">"Notiek ielāde..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Visas atļaujas"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Citas lietotnes atļaujas"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Atļaujas pieprasījums"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Konstatēts ekrāna pārklājums"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Lai mainītu šo atļaujas iestatījumu, vispirms sadaļā “Iestatījumi un lietotnes” izslēdziet ekrāna pārklājumu."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Atvērt iestatījumus"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ierīcē netiek atbalstīta instalēšana/atinstalēšana"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Izvēlieties, kādas piekļuves atļaujas piešķirt lietotnei <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Lietotne <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ir atjaunināta. Izvēlieties, kādas piekļuves atļaujas tai piešķirt."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Atcelt"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Turpināt"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Jaunas atļaujas"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Pašreizējās atļaujas"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Lietotne tiek izstādīta…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Nezināms"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Drošības nolūkos jūsu planšetdatorā nedrīkst instalēt no šī avota iegūtas nezināmas lietotnes."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Drošības nolūkos jūsu televizorā nedrīkst instalēt no šī avota iegūtas nezināmas lietotnes."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Drošības nolūkos jūsu tālrunī nedrīkst instalēt no šī avota iegūtas nezināmas lietotnes."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Jūsu tālruņa un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par tālruņa bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Jūsu planšetdatora un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par planšetdatora bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Jūsu televizora un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par televizora bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Turpināt"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Iestatījumi"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear lietotņu instalēšana/atinstalēšana"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mk-television/strings.xml b/packages/PackageInstaller/res/values-mk-television/strings.xml
new file mode 100644
index 0000000..bb3ea92
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mk-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Одбиј и не прашувај повторно"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Може да го промените ова подоцна во Поставки > Апликации"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Прикажи ги системските апликации"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Дозволи за апликацијата"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Дозволи за апликацијата"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Дозволи за <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Дополнителни дозволи"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Дозволи за <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mk-watch/strings.xml b/packages/PackageInstaller/res/values-mk-watch/strings.xml
new file mode 100644
index 0000000..5906f56
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mk-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Одбиј, не прашувај повторно"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Прикажи ги системските апликации"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Не може да се смени"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Да"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Откажи"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
new file mode 100644
index 0000000..8cf208e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Инсталатор на пакет"</string>
+ <string name="next" msgid="3057143178373252333">"Следно"</string>
+ <string name="install" msgid="5896438203900042068">"Инсталирај"</string>
+ <string name="done" msgid="3889387558374211719">"Готово"</string>
+ <string name="cancel" msgid="8360346460165114585">"Откажи"</string>
+ <string name="installing" msgid="8613631001631998372">"Се инсталира..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Се инсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Апликацијата е инсталирана."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Дали сакате да ја инсталирате оваа апликација? Ќе добие пристап до:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Дали сакате да ја инсталирате оваа апликација? Не бара никаков посебен пристап."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Дали сакате да инсталирате надградба на оваа постоечка апликација? Вашите постоечки податоци нема да се изгубат. Ажурираната апликација ќе добие пристап до:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Дали сакате да инсталирате надградба на оваа вградена апликација? Вашите постоечки податоци нема да се изгубат. Ажурираната апликација ќе добие пристап до:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Дали сакате да инсталирате надградба на оваа постоечка апликација? Вашите постоечки податоци нема да се изгубат. Таа не бара никаков посебен пристап."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Дали сакате да инсталирате надградба на оваа вградена апликација? Вашите постоечки податоци нема да се изгубат. Таа не бара никаков посебен пристап."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Апликацијата не е инсталирана."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Инсталирањето на пакетот е блокирано."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Апликација што не е инсталирана како пакет е во конфликт со постоен пакет."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Апликација што не е инсталирана како апликација не е компатибилна со вашиот таблет."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Оваа апликација не е компатибилна со вашиот телевизор."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Апликација што не е инсталирана како апликација не е компатибилна со вашиот телефон."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Апликација што не е инсталирана како пакет се чини дека е неважечка."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира на вашиот таблет."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> не може да се инсталира на вашиот телевизор."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира на вашиот телефон."</string>
+ <string name="launch" msgid="4826921505917605463">"Отвори"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Вашиот администратор не дозволува инсталација на апликации добиени од непознати извори"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Корисников не може да инсталира непознати апликации"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"На корисников не му е дозволено да инсталира апликации"</string>
+ <string name="ok" msgid="3468756155452870475">"Во ред"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Управувај со апликации"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Нема простор"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира. Ослободете простор и обидете се повторно."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Апликацијата не е пронајдена"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Апликацијата не е пронајдена во списокот инсталирани апликации."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Не е дозволено"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Тековниот корисник нема дозвола да ја изведе деинсталацијава."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Грешка"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Не можеше да се деинсталира апликацијата."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Деинсталирај апликација"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Деинсталирај ажурирање"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> е дел од следната апликација:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Дали сакате да ја деинсталирате оваа апликација?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Дали сакате да ја деинсталирате оваа апликација за "<b>"сите"</b>" корисници? Апликацијата и нејзините податоци ќе се отстранат од "<b>"сите"</b>" корисници на уредот."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Дали сакате да ја деинсталирате апликацијава за корисникот <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Сакате да ја замените оваа апликација со фабричката верзија? Сите податоци ќе се отстранат."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Сакате да ја замените оваа апликација со фабричката верзија? Сите податоци ќе се отстранат. Тоа важи за сите корисници на овој уред, вклучувајќи ги и тие со работни профили."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Деинсталации во тек"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Неуспешни деинсталации"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Се деинсталира..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Се деинсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Деинсталирањето заврши."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> е деинсталиран"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Деинсталирањето е неуспешно."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Деинсталирањето на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> е неуспешно."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Не може да се деинсталира активна апликација на администраторот на уредот"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Не може да се деинсталира активна апликација на администраторот на уредот за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Апликацијата е неопходна за некои корисници или профили, а за другите е деинсталирана"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Апликацијата е потребна за вашиот профил и не може да се деинсталира."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Апликацијата ја бара администраторот на вашиот уред и не може да се деинсталира."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Управувај со аплик. за администраторот на уредот"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Управувај со корисници"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> не може да се деинсталира."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Настана проблем при разложување на пакетот."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Ново"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Сè"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Приватност"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Пристап кон уредот"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Ова ажурирање не бара нови дозволи."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Одбиј"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Повеќе информации"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Сепак одбиј"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> од <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Дозволете <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Дали секогаш да се дозволи <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Само додека се користи апликацијата"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Секогаш"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Одбиј и не прашувај повторно"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Оневозможени се <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"сите се оневозможени"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ниедна не е оневозможена"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Овозможи"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Апликации"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Дозволи за апликацијата"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Не прашувај повторно"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Нема дозволи"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Дополнителни дозволи"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Отвора информации за апликација"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Уште <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Уште <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Оваа апликација е дизајнирана за постара верзија на Android. Одбивањето на дозволата може да предизвика веќе да не функционира како што треба."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"изврши непознато дејство"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Дозволени се <xliff:g id="COUNT_0">%1$d</xliff:g> од <xliff:g id="COUNT_1">%2$d</xliff:g> апликации"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Прикажи систем"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Сокриј систем"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Нема апликации"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Поставки за локација"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> е давател на услуги според локација за овој уред. Пристапот до локацијата може да се смени од Поставките за локација."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ако ја одбиете оваа дозвола, основните функции на вашиот уред можеби веќе нема да функционираат како што треба."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Наложено од политиката"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Пристапот од заднина е оневозможен со правилото"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Пристапот од заднина е овозможен со правилото"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Пристапот од преден план е овозможен со правилото"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролирано од администраторот"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Секогаш"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Само додека се користи аплик."</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Никогаш"</string>
+ <string name="loading" msgid="7811651799620593731">"Се вчитува..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Сите дозволи"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Други можности на апликацијата"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Барање дозвола"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Откривме преклопување на екранот"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"За да ја измените оваа поставка за дозвола, прво мора да го исклучите преклопувањето на екранот од Поставки > Апликации"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Отвори поставки"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Дејствата инсталирај/деинсталирај не се поддржани на Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Изберете што да ѝ се овозможи на <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> за пристап"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> е ажурирана. Изберете што да ѝ се овозможи на оваа апликација за пристап."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Откажи"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Продолжи"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Нови дозволи"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Тековни дозволи"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Апликацијата се поставува…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Непознато"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"За ваша безбедност, таблетот нема дозвола за инсталирање непознати апликации од изворов."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"За ваша безбедност, телевизорот нема дозвола за инсталирање непознати апликации од изворов."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"За ваша безбедност, телефонот нема дозвола за инсталирање непознати апликации од изворов."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефонот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телефонот или губењето податоци што може да произлезат од нејзиното користење."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таблетот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на таблетот или губењето податоци што може да произлезат од нејзиното користење."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Телевизорот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телевизорот или губењето податоци што може да произлезат од нејзиното користење."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Продолжи"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Поставки"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Се инсталираат/деинсталираат аплик. Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ml-television/strings.xml b/packages/PackageInstaller/res/values-ml-television/strings.xml
new file mode 100644
index 0000000..5ede01f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ml-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"നിരസിക്കുക, വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"പിന്നീട് നിങ്ങൾക്കിത് ക്രമീകരണവും ആപ്സും എന്നതിൽ മാറ്റാനാകും"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"സിസ്റ്റം ആപ്സ് കാണിക്കുക"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ആപ്പ് അനുമതികൾ"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ആപ്പ് അനുമതികൾ"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> അനുമതികൾ"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"അധിക അനുമതികൾ"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> അനുമതികൾ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ml-watch/strings.xml b/packages/PackageInstaller/res/values-ml-watch/strings.xml
new file mode 100644
index 0000000..13e3876
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ml-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"നിരസിക്കുക, വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"സിസ്റ്റം ആപ്സ് കാണിക്കുക"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"മാറ്റാനാവില്ല"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"അതെ"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"റദ്ദാക്കുക"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml
new file mode 100644
index 0000000..9fadd24
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ml/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"പാക്കേജ് ഇൻസ്റ്റാളർ"</string>
+ <string name="next" msgid="3057143178373252333">"അടുത്തത്"</string>
+ <string name="install" msgid="5896438203900042068">"ഇൻസ്റ്റാളുചെയ്യുക"</string>
+ <string name="done" msgid="3889387558374211719">"പൂർത്തിയായി"</string>
+ <string name="cancel" msgid="8360346460165114585">"റദ്ദാക്കുക"</string>
+ <string name="installing" msgid="8613631001631998372">"ഇൻസ്റ്റാൾ ചെയ്യുന്നു..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ഇൻസ്റ്റാൾ ചെയ്യുന്നു…"</string>
+ <string name="install_done" msgid="3682715442154357097">"അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തു."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്യണോ? ഇതിന് ഇവയിലേക്ക് ആക്സസ്സ് ലഭിക്കും:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"നിങ്ങൾക്ക് ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്യണോ? ഇത് പ്രത്യേക ആക്സസ്സൊന്നും ആവശ്യമില്ല."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"നിലവിലുള്ള ഈ അപ്ലിക്കേഷന് ഒരു അപ്ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്ടപ്പെടില്ല. അപ്ഡേറ്റുചെയ്ത അപ്ലിക്കേഷന് ഇവയിലേക്ക് ആക്സസ്സ് ലഭിക്കും:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ഈ അന്തർ നിർമ്മിത അപ്ലിക്കേഷന് ഒരു അപ്ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്ടപ്പെടില്ല. അപ്ഡേറ്റുചെയ്ത അപ്ലിക്കേഷന് ഇവയിലേക്ക് ആക്സസ്സ് ലഭിക്കും:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"നിലവിലുള്ള ഈ അപ്ലിക്കേഷന് ഒരു അപ്ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്ടപ്പെടില്ല. ഇതിന് പ്രത്യേക ആക്സസ്സൊന്നും ആവശ്യമില്ല."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ഈ അന്തർ നിർമ്മിത അപ്ലിക്കേഷന് ഒരു അപ്ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്ടപ്പെടില്ല. ഇതിന് പ്രത്യേക ആക്സസ്സൊന്നും ആവശ്യമില്ല."</string>
+ <string name="install_failed" msgid="6579998651498970899">"അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്തില്ല."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ഇൻസ്റ്റാൾ ചെയ്യുന്നതിൽ നിന്നും പാക്കേജിനെ തടഞ്ഞു."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"നിലവിലുള്ള ഒരു പാക്കേജുമായി പാക്കേജിന് പൊരുത്തക്കേടുള്ളതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"നിങ്ങളുടെ ടാബ്ലെറ്റുമായി അനുയോജ്യത ഇല്ലാത്തതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"നിങ്ങളുടെ ടിവിയ്ക്ക് ഈ ആപ്പ് അനുയോജ്യമല്ല."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"നിങ്ങളുടെ ഫോണുമായി അനുയോജ്യത ഇല്ലാത്തതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"പാക്കേജ് അസാധുവായി കാണപ്പെടുന്നതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"നിങ്ങളുടെ ടാബ്ലെറ്റിൽ <xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>, നിങ്ങളുടെ ടിവിയിൽ ഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"നിങ്ങളുടെ ഫോണിൽ <xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
+ <string name="launch" msgid="4826921505917605463">"തുറക്കുക"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"അജ്ഞാത ഉറവിടങ്ങളിൽ നിന്ന് സ്വന്തമാക്കിയ ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ അഡ്മിനിസ്ട്രേറ്റർ അനുവദിക്കുന്നില്ല"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ഈ ഉപയോക്താവിന്, തിരിച്ചറിയാനാകാത്ത ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുന്നതിന് ഈ ഉപയോക്താവിന് അനുവാദമില്ല"</string>
+ <string name="ok" msgid="3468756155452870475">"ശരി"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"അപ്ലിക്കേഷനുകൾ നിയന്ത്രിക്കുക"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"പരിധി കഴിഞ്ഞു"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്റ്റാളുചെയ്യാനായില്ല. കുറച്ച് ഇടം ശൂന്യമാക്കിയതിനുശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"അപ്ലിക്കേഷൻ കണ്ടെത്തിയില്ല"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ഇൻസ്റ്റാളുചെയ്ത അപ്ലിക്കേഷനുകളുടെ ലിസ്റ്റിൽ അപ്ലിക്കേഷൻ കണ്ടെത്തിയില്ല."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"അനുവദിച്ചിട്ടില്ല"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ഈ അൺഇൻസ്റ്റലേഷൻ നിർവഹിക്കാൻ നിലവിലെ ഉപയോക്താവിനെ അനുവദിച്ചിട്ടില്ല."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"പിശക്"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിഞ്ഞില്ല."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"അപ്ലിക്കേഷൻ അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"അപ്ഡേറ്റ് അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> എന്നത് ഇനിപ്പറയുന്ന അപ്ലിക്കേഷന്റെ ഭാഗമാണ്:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ഈ അപ്ലിക്കേഷൻ അൺഇൻസ്റ്റാളുചെയ്യണോ?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ഈ അപ്ലിക്കേഷൻ "<b>"എല്ലാ"</b>" ഉപയോക്താക്കൾക്കുമായി അൺഇൻസ്റ്റാളുചെയ്യണോ? ഉപകരണത്തിലെ "<b>"എല്ലാ"</b>" ഉപയോക്താക്കളിൽ നിന്നും അപ്ലിക്കേഷനും അതിന്റെ ഡാറ്റയും നീക്കംചെയ്യപ്പെടും."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിനായി ഈ അപ്ലിക്കേഷൻ അൺഇൻസ്റ്റാളുചെയ്യണോ?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ഫാക്ടറി പതിപ്പ് ഉപയോഗിച്ച് ഈ ആപ്പ് മാറ്റിസ്ഥാപിക്കണോ? എല്ലാ ഡാറ്റയും നീക്കംചെയ്യപ്പെടും."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ഫാക്ടറി പതിപ്പ് ഉപയോഗിച്ച് ഈ ആപ്പ് മാറ്റിസ്ഥാപിക്കണോ? എല്ലാ ഡാറ്റയും നീക്കംചെയ്യപ്പെടും. ഔദ്യോഗിക പ്രൊഫൈലുകൾ ഉള്ളവർ ഉൾപ്പെടെ, ഈ ഉപകരണത്തിന്റെ എല്ലാ ഉപയോക്താക്കളെയും ഇത് ബാധിക്കുന്നു."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"അൺ ഇൻസ്റ്റാൾ ചെയ്തുകൊണ്ടിരിക്കുന്നവ"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"അൺ ഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയാഞ്ഞവ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"അൺഇൻസ്റ്റാൾ ചെയ്യുന്നു..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺഇൻസ്റ്റാൾ ചെയ്യുന്നു…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"അൺഇൻസ്റ്റാളുചെയ്യൽ പൂർത്തിയായി."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺഇൻസ്റ്റാൾ ചെയ്തു"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"അൺഇൻസ്റ്റാളുചെയ്തു."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺഇൻസ്റ്റാൾ ചെയ്യൽ പരാജയം."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"സജീവ ഉപകരണ അഡ്മിൻ ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിന്റെ സജീവ ഉപകരണ അഡ്മിൻ ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ചില ഉപയോക്താക്കൾക്കോ പ്രൊഫൈലുകൾക്കോ ഈ ആപ്പ് ആവശ്യമാണ്, മറ്റുള്ളവർക്ക് ഈ ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിന് ഈ ആപ്പ് ആവശ്യമുള്ളതിനാൽ അത് അൺഇൻസ്റ്റാൾ ചെയ്യാനാവില്ല."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"നിങ്ങളുടെ ഉപകരണ അഡ്മിനിസ്ട്രേറ്ററിന് ഈ അപ്ലിക്കേഷൻ ആവശ്യമുള്ളതിനാൽ ഇത് അൺഇൻസ്റ്റാൾ ചെയ്യാനാവില്ല."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ഉപകരണ അഡ്മിൻ ആപ്പുകളെ മാനേജുചെയ്യുക"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ഉപയോക്താക്കളെ മാനേജുചെയ്യുക"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> അൺഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"പാക്കേജ് പാഴ്സുചെയ്യുന്നതിൽ ഒരു പ്രശ്നമുണ്ടായിരുന്നു."</string>
+ <string name="newPerms" msgid="6039428254474104210">"പുതിയത്"</string>
+ <string name="allPerms" msgid="1024385515840703981">"എല്ലാം"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"സ്വകാര്യത"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ഉപകരണ ആക്സസ്സ്"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ഈ അപ്ഡേറ്റിന് പുതിയ അനുമതികളൊന്നും ആവശ്യമില്ല."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"നിരസിക്കുക"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"കൂടുതൽ വിവരങ്ങള്"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"എന്തായാലും നിരസിക്കുക"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<xliff:g id="ACTION">%2$s</xliff:g> <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ആപ്പിനെ അനുവദിക്കണോ?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> എന്നതിനെ എല്ലായ്പ്പോഴും <xliff:g id="ACTION">%2$s</xliff:g> എന്നതിന് അനുവദിക്കണമോ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ആപ്പ് ഉപയോഗിക്കുമ്പോൾ മാത്രം"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"എല്ലായ്പ്പോഴും"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"നിരസിക്കുക, വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"എല്ലാം പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ഒന്നും പ്രവർത്തനരഹിതമാക്കിയിട്ടില്ല"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"അനുവദിക്കുക"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ആപ്സ്"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ആപ്പ് അനുമതികൾ"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"അനുമതികൾ ഇല്ല"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"അധിക അനുമതികൾ"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ആപ്പ് വിവരം തുറക്കുക"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> എണ്ണം കൂടി</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> എണ്ണം കൂടി</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ഈ ആപ്പ് Android-ന്റെ പഴയ പതിപ്പിനായാണ് രൂപകൽപ്പന ചെയ്തിരിക്കുന്നത്. അനുമതി നിരസിക്കുന്നത് തുടർന്ന് ഉദ്ദേശിച്ചവിധം പ്രവർത്തിക്കാതിരിക്കാനിടയാക്കുന്നു."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ഒരു അജ്ഞാതപ്രവർത്തനം നടത്തുക"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="COUNT_1">%2$d</xliff:g> ആപ്പുകൾ അനുവദനീയം"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"സിസ്റ്റം കാണിക്കുക"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"സിസ്റ്റം മറയ്ക്കുക"</string>
+ <string name="no_apps" msgid="1965493419005012569">"ആപ്സ് ഒന്നുമില്ല"</string>
+ <string name="location_settings" msgid="1774875730854491297">"ലൊക്കേഷൻ ക്രമീകരണം"</string>
+ <string name="location_warning" msgid="8778701356292735971">"ഈ ഉപകരണത്തിനായുള്ള ലൊക്കേഷൻ സേവനങ്ങളുടെ ദാതാവ് <xliff:g id="APP_NAME">%1$s</xliff:g> ആണ്. ലൊക്കേഷൻ ക്രമീകരണത്തിൽ നിന്ന് ലൊക്കേഷൻ ആക്സസ് പരിഷ്കരിക്കാവുന്നതാണ്."</string>
+ <string name="system_warning" msgid="7103819124542305179">"നിങ്ങൾ ഈ അനുമതി നിഷേധിക്കുന്നുവെങ്കിൽ, നിങ്ങളുടെ ഉപകരണത്തിന്റെ അടിസ്ഥാന ഫീച്ചറുകൾ ഉദ്ദേശിച്ചത് പോലെ തുടർന്ന് പ്രവർത്തിച്ചേക്കില്ല."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"നയം മുഖേനെ നടപ്പിലാക്കിയത്"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"നയം അനുസരിച്ച് ബാക്ക്ഗ്രൗണ്ട് ആക്സസ് പ്രവർത്തനരഹിതമാക്കി"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"നയം അനുസരിച്ച് ബാക്ക്ഗ്രൗണ്ട് ആക്സസ് പ്രവർത്തനക്ഷമമാക്കി"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"നയം അനുസരിച്ച് ഫോർഗ്രൗണ്ട് ആക്സസ് പ്രവർത്തനക്ഷമമാക്കി"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"അഡ്മിൻ നിയന്ത്രിക്കുന്നത്"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"എല്ലായ്പ്പോഴും"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ആപ്പ് ഉപയോഗിക്കുമ്പോൾ മാത്രം"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ഒരിക്കലും"</string>
+ <string name="loading" msgid="7811651799620593731">"ലോഡുചെയ്യുന്നു..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"എല്ലാ അനുമതികളും"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"മറ്റ് ആപ്പ് ശേഷികൾ"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"അനുമതി അഭ്യർത്ഥന"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"സ്ക്രീൻ ഓവർലേ കണ്ടെത്തി"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ഈ അനുമതി ക്രമീകരണം മാറ്റുന്നതിന്, ക്രമീകരണം > ആപ്സ് എന്നതിൽ നിന്ന് നിങ്ങളാദ്യം സ്ക്രീൻ ഓവർലേ ഓഫാക്കേണ്ടതാണ്"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ക്രമീകരണം തുറക്കുക"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ഇൻസ്റ്റാളോ അൺഇൻസ്റ്റാളോ ചെയ്യുന്നതിന് Wear-ൽ പിന്തുണയില്ല"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"എന്തൊക്കെ ആക്സസ്സ് ചെയ്യാനാണ് <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ആപ്പിനെ അനുവദിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> അപ്ഡേറ്റ് ചെയ്തിരിക്കുന്നു. എന്തൊക്കെ ആക്സസ്സ് ചെയ്യാനാണ് ഈ ആപ്പിനെ അനുവദിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"റദ്ദാക്കുക"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"തുടരുക"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"പുതിയ അനുമതികൾ"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"നിലവിലെ അനുമതികൾ"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ആപ്പ് തയ്യാറാക്കുന്നു…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"അജ്ഞാതം"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"നിങ്ങളുടെ സുരക്ഷയ്ക്ക്, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, തിരിച്ചറിയാനാകാത്ത ആപ്സ് ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ ടാബ്ലെറ്റ് അനുവദിക്കപ്പെടില്ല."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"നിങ്ങളുടെ സുരക്ഷയ്ക്ക്, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, തിരിച്ചറിയാനാകാത്ത ആപ്സ് ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ ടിവി അനുവദിക്കപ്പെടില്ല."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"നിങ്ങളുടെ സുരക്ഷയ്ക്ക്, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, തിരിച്ചറിയാനാകാത്ത ആപ്സ് ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ ഫോൺ അനുവദിക്കപ്പെടില്ല."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"തിരിച്ചറിയാനാകാത്ത ആപ്പുകളാൽ നിങ്ങളുടെ ഫോണും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ഫോണിന് സംഭവിച്ചേക്കാവുന്ന എല്ലാ നാശനഷ്ടങ്ങൾക്കും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്ടങ്ങൾക്കും നിങ്ങൾക്കാണ് ഉത്തരവാദിത്തമെന്ന് നിങ്ങൾ അംഗീകരിക്കുന്നു."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"തിരിച്ചറിയാനാകാത്ത ആപ്പുകളാൽ നിങ്ങളുടെ ടാബ്ലെറ്റും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ടാബ്ലെറ്റിന് സംഭവിച്ചേക്കാവുന്ന എല്ലാ നാശനഷ്ടങ്ങൾക്കും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്ടങ്ങൾക്കും നിങ്ങൾക്കാണ് ഉത്തരവാദിത്തമെന്ന് നിങ്ങൾ അംഗീകരിക്കുന്നു."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"തിരിച്ചറിയാനാകാത്ത ആപ്പുകളാൽ നിങ്ങളുടെ ടിവിയും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ടിവിക്ക് സംഭവിച്ചേക്കാവുന്ന എല്ലാ നാശനഷ്ടങ്ങൾക്കും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്ടങ്ങൾക്കും നിങ്ങൾക്കാണ് ഉത്തരവാദിത്തമെന്ന് നിങ്ങൾ അംഗീകരിക്കുന്നു."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"തുടരുക"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ക്രമീകരണം"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear ആപ്പുകൾ ഇൻസ്റ്റാൾ/അൺ ഇൻസ്റ്റാൾ ചെയ്യൽ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mn-television/strings.xml b/packages/PackageInstaller/res/values-mn-television/strings.xml
new file mode 100644
index 0000000..39c899f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mn-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Taтгалзаад дахин бүү асуугаарай"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Та дараа үүнийг Toхиргоо & Апп дотроос солих боломжтой"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Системийн аппыг харуулах"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Апп-н зөвшөөрөл"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Апп-н зөвшөөрөл"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> зөвшөөрөл"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Нэмэлт зөвшөөрөл"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> зөвшөөрөл"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mn-watch/strings.xml b/packages/PackageInstaller/res/values-mn-watch/strings.xml
new file mode 100644
index 0000000..120c336
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mn-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Татгалзах, дахин бүү асуугаарай"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Системийн аппыг харуулах"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Өөрчлөх боломжгүй"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Тийм"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Цуцлах"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
new file mode 100644
index 0000000..1fd12a2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Багц суулгагч"</string>
+ <string name="next" msgid="3057143178373252333">"Дараах"</string>
+ <string name="install" msgid="5896438203900042068">"Суулгах"</string>
+ <string name="done" msgid="3889387558374211719">"Дуусгах"</string>
+ <string name="cancel" msgid="8360346460165114585">"Цуцлах"</string>
+ <string name="installing" msgid="8613631001631998372">"Суулгаж байна…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г суулгаж байна…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Апп суулгагдсан."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Та энэ аппликешныг суулгамаар байна уу? Энэ дараахад хандах болно:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Та энэ аппликешныг суулгах уу? Энэ тусгай хандалт шаардахгүй."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Та энэ аппликейшны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Шинэчлэгдсэн аппликейшн нь дараахад хандаж чадна:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Та энэ үндсэн аппликейшны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Шинэчлэгдсэн аппликейшн нь дараахад хандаж чадна:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Та энэ аппликешны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Энэ ямар нэгэн тусгай эрх шаардахгүй."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Та энэ үндсэн аппликешны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Энэ ямар нэгэн тусгай эрх шаардахгүй."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Апп суулгагдаагүй."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Багц суулгахыг блоклосон байна."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Багц одоогийн багцтай тохирохгүй байгаа тул апп-г суулгаж чадсангүй."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Апп таны таблеттай тохирохгүй байгаа тул үүнийг суулгасангүй."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Энэ апп нь таны ТВ-д нийцэхгүй."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Апп таны утсанд тохирохгүй байгаа тул үүнийг суулгасангүй."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Багц хүчингүй тул апп-г суулгасангүй."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны таблет дээр суусангүй."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны телевизэд суурилуулах боломжгүй байна."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г таны утсан дээр суулгах боломжгүй."</string>
+ <string name="launch" msgid="4826921505917605463">"Нээх"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Таны админ тодорхойгүй сурвалжаас татсан апп суулгахыг зөвшөөрдөггүй"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Энэ хэрэглэгч тодорхойгүй апп суулгах боломжгүй байна"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Энэ хэрэглэгч апп суулгах зөвшөөрөлгүй байна"</string>
+ <string name="ok" msgid="3468756155452870475">"ОК"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Апп удирдах"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Зай дутагдаж байна"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г суулгаж чадсангүй. Зайг чөлөөлөөд дахин оролдоно уу."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Апп олдсонгүй"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Суулгасан апп-н жагсаалт дотроос апп олдсонгүй."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Зөвшөөрөөгүй"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Одоогийн хэрэглэгч үүнийг устгах боломжгүй."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Алдаа"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Апп-г устгаж чадсангүй."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Апп устгах"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Шинэчлэлийг устгах"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> нь дараах апп-н хэсэг болно:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Та энэ апп-г устгамаар байна уу?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Та энэ апп-г "<b>"бүх"</b>" хэрэглэгчээс устгах уу? Аппикешн болон доторх дата нь төхөөрөмж дээрх "<b>"бүх"</b>" хэрэглэгчээс устгагдах болно."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Та энэ апп-г <xliff:g id="USERNAME">%1$s</xliff:g> хэрэглэгчийн хувьд устгах уу?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Энэ апп-г үйлдвэрээс ирсэн хувилбараар нь солих уу? Бүх өгөгдөл устах болно."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Энэ апп-г үйлдвэрээс ирсэн хувилбараар нь солих уу? Бүх өгөгдөл устах болно. Энэ нь ажлын профайлтай хэрэглэгч зэрэг энэ төхөөрөмжийн бүх хэрэглэгчдэд үйлчлэх болно."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Устгаж байна"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Устгаж чадсангүй"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Устгаж байна…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж байна…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Устгаж дуусав."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгасан"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Устгалт амжилтгүй болов."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж чадсангүй."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Идэвхтэй төхөөрөмжийн админ аппыг устгах боломжгүй"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>-д идэвхтэй төхөөрөмжийн админ аппыг устгах боломжгүй байна"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Энэ апп нь зарим хэрэглэгч эсвэл профайлд шаардлагатай учир үүнийг тэдгээрээс бусад хэрэглэгчдээс устгасан"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Энэ апп таны профайлд шаардлагатай бөгөөд устгах боломжгүй."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Энэ апп нь таны төхөөрөмжийн админд шаардлагатай бөгөөд устгах боломжгүй."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Төхөөрөмжийн админ аппыг удирдах"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Хэрэгчлэгчдийг удирдах"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г устгаж чадсангүй."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Багцийг задлахад алдаа гарав."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Шинэ"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Бүгд"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Нууцлал"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Төхөөрөмжид хандах"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Энэ шинэчлэл шинэ зөвшөөрөл шаардахгүй."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Татгалзах"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Дэлгэрэнгүй мэдээлэл"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Хэдийд ч татгалзах"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-ийн <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-г <xliff:g id="ACTION">%2$s</xliff:g>-г зөвшөөрөх үү?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-г <xliff:g id="ACTION">%2$s</xliff:g>-д байнга зөвшөөрөх үү?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Зөвхөн апп ашиглах үед"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Байнга"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Taтгалзаад дахин бүү асуугаарай"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>-г цуцалсан"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"бүгдийг цуцалсан"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"алийг ч цуцлаагүй"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Зөвшөөрөх"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Апп"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Апп зөвшөөрөл"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Дахиж бүү асуу"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Зөвшөөрөлгүй байна"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Нэмэлт зөвшөөрөл"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Аппын мэдээллийг нээх"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> бусад</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> бусад</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Энэхүү аппыг нь Android-ын хуучин хувилбарт зориулсан. Зөвшөөрлийг үгүйсгэх нь цаашид ажиллахгүй болгож болно."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"Танигдаагүй үйлдлийг гүйцэтгэх"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>-с <xliff:g id="COUNT_0">%1$d</xliff:g> аппыг зөвшөөрдөг"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Системийг харуулах"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Системийг нуух"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Апп байхгүй"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Байршлын тохиргоо"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь энэ төхөөрөмжийн байршлын үйлчилгээ үзүүлэгч юм. Байршилд хандалтыг байршлын тохиргоо хэсгээс өөрчилж болно."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Хэрэв та энэ зөвшөөрөлд татгалзсан тохиолдолд таны төхөөрөмжийн үндсэн функц нь алдаатай ажиллаж магадгүй."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Бодлогын дагуу хэрэгжсэн"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Арын дэвсгэрийн хандалтыг удирдамжаас идэвхгүй болгосон"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Арын дэвсгэрийн хандалтыг удирдамжаас идэвхтэй болгосон"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Нүүрний дэвсгэрийн хандалтыг удирдамжаас идэвхтэй болгосон"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Админ удирддаг"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Байнга"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Зөвхөн апп ашиглах үед"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Хэзээ ч үгүй"</string>
+ <string name="loading" msgid="7811651799620593731">"Ачаалж байна..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Бүх зөвшөөрөл"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Бусад апп-ын боломж"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Зөвшөөрлийн хүсэлт"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Дэлгэцийн давхарга илрүүллээ"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Зөвшөөрлийн тохиргоог өөрчлөхийн тулд, эхлээд Тохиргоо ба Апп хэсгээс дэлгэцийн давхаргыг унтраана уу."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Тохиргоог нээх"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Суулгах/Устгах үйлдлийг Wear дэмжээгүй."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-н хандаж болох зүйлсийг сонгоно уу"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>-г шинэчиллээ. Энэ апп-н хандаж болох зүйлсийг сонгоно уу."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Цуцлах"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Үргэлжлүүлэх"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Шинэ зөвшөөрөл"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Одоогийн зөвшөөрөл"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Апп-г байршуулж байна…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Тодорхойгүй"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Таны аюулгүй байдлыг хангахын тулд таны таблет энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Таны аюулгүй байдлыг хангахын тулд таны ТВ энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Таны аюулгүй байдлыг хангахын тулд таны утас энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Таны утас болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны утсанд гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таны таблет болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны таблетад гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Таны ТВ болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны ТВ-д гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Үргэлжлүүлэх"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Тохиргоо"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Зүүсгэл аппыг суулгаж/устгаж байна"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mr-television/strings.xml b/packages/PackageInstaller/res/values-mr-television/strings.xml
new file mode 100644
index 0000000..e648404
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mr-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"नकार द्या आणि पुन्हा विचारू नका"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"तुम्ही हे नंतर सेटिंग्ज आणि अॅप्स मध्ये बदलू शकता"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"सिस्टम अॅप्स दर्शवा"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"अॅप परवानग्या"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"अॅप परवानग्या"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> परवानग्या"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"अतिरिक्त परवानग्या"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> परवानग्या"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mr-watch/strings.xml b/packages/PackageInstaller/res/values-mr-watch/strings.xml
new file mode 100644
index 0000000..74d32df
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mr-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"नकार द्या, पुन्हा विचारू नका"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"सिस्टम अॅप्स दर्शवा"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"बदलू शकत नाही"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"होय"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"रद्द करा"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
new file mode 100644
index 0000000..b9acaa5
--- /dev/null
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"पॅकेज स्थापनकर्ता"</string>
+ <string name="next" msgid="3057143178373252333">"पुढील"</string>
+ <string name="install" msgid="5896438203900042068">"स्थापित करा"</string>
+ <string name="done" msgid="3889387558374211719">"पूर्ण झाले"</string>
+ <string name="cancel" msgid="8360346460165114585">"रद्द करा"</string>
+ <string name="installing" msgid="8613631001631998372">"इंस्टॉल करत आहे..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इन्स्टॉल करत आहे…"</string>
+ <string name="install_done" msgid="3682715442154357097">"अॅप इंस्टॉल झाला."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"तुम्ही हा अॅप्लिकेशन इंस्टॉल करू इच्छिता? यास यावर प्रवेश मिळेल:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"तुम्ही हा अॅप्लिकेशन इंस्टॉल करू इच्छिता? यास कोणत्याही विशेष प्रवेशाची आवश्यकता नसते."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"तुम्हाला सद्य अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. अपडेट केलेल्या अॅप्लिकेशनला यावर अॅक्सेस मिळेल:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"तुम्ही या बिल्ट-इन अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. अपडेट केलेल्या अॅप्लिकेशनला यावर अॅक्सेस मिळेल:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"तुम्हाला सद्य अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. यासाठी कोणताही विशेष अॅक्सेस आवश्यक नसतो."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"तुम्ही या बिल्ट-इन अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. यासाठी कोणताही विशेष अॅक्सेस आवश्यक नसतो."</string>
+ <string name="install_failed" msgid="6579998651498970899">"अॅप इंस्टॉल झाला नाही."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"पॅकेेच इंस्टॉल होण्यास अवरोधित केलेले होते."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अॅप इंस्टॉल केला नाही."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"अॅप आपल्या टॅब्लेटशी सुसंगत नसल्याने अॅप इंस्टॉल केला नाही."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"हा अॅप आपल्या टीव्हीशी सुसंगत नाही."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"अॅप आपल्या फोनशी सुसंगत नसल्याने अॅप इंस्टॉल केला नाही."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"पॅकेज अवैध असल्याचे दिसत असल्याने अॅप इंस्टॉल केले नाही."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपल्या टॅब्लेटवर इंस्टॉल केला जाऊ शकला नाही."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपल्या टीव्हीवर इंस्टॉल केले जाऊ शकले नाही."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपल्या फोनवर इंस्टॉल केला जाऊ शकला नाही."</string>
+ <string name="launch" msgid="4826921505917605463">"उघडा"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"अज्ञात स्रोतांकडून मिळवलेल्या अॅप्सच्या स्थापनेला आपला प्रशासक अनुमती देत नाही"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"या वापरकर्त्याद्वारे अज्ञात अॅप्स इंस्टॉल केली जाऊ शकत नाहीत"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"या वापरकर्त्याला अॅप्स इंस्टॉल करण्याची परवानगी नाही"</string>
+ <string name="ok" msgid="3468756155452870475">"ठीक"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"अॅप्स व्यवस्थापित करा"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"स्थानाबाहेर"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> इंस्टॉल केला जाऊ शकला नाही. काही स्थान मोकळे करा आणि पुन्हा प्रयत्न करा."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"अॅप आढळला नाही"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"इंस्टॉल केलेल्या अॅप्सच्या सूचीमध्ये अॅप आढळला नाही."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"अनुमती नाही"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"हे अनइंस्टॉल करण्याची वर्तमान वापरकर्त्यास अनुमती नाही."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"एरर"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"अॅप अनइंस्टॉल करणे शक्य झाले नाही."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"अॅप अनइंस्टॉल करा"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"अपडेट अनइंस्टॉल करा"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> खालील अॅप चा भाग आहे:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"तुम्ही हा अॅप अनइंस्टॉल करू इच्छिता?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"तुम्ही हा अॅप "<b>"सर्व"</b>" वापरकर्त्यांसाठी अनइंस्टॉल करू इच्छिता? अॅप्लिकेशन आणि त्याचा डेटा डिव्हाइसवरील "<b>"सर्व"</b>" वापरकर्त्यांवरून काढला जाईल."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"तुम्ही <xliff:g id="USERNAME">%1$s</xliff:g> वापरकर्त्यासाठी हा अॅप विस्थापित करु इच्छिता?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"फॅक्टरी आवृत्तीसह हा अॅप पुनर्स्थित करायचा? सर्व डेटा काढला जाईल."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"फॅक्टरी आवृत्तीसह हा अॅप पुनर्स्थित करायचा? सर्व डेटा काढला जाईल. हे कार्य प्रोफाईल असलेल्यांसह या डिव्हाइसच्या सर्व वापरकर्त्यांना प्रभावित करते."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"अनइंस्टॉल करणे चालू आहे"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"अनइंस्टॉल करणे अयशस्वी झाले"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"अनइंस्टॉल करत आहे…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करत आहे…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"अनइंस्टॉल करणे समाप्त."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल केले"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"अनइंस्टॉल करणे अयशस्वी."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करणे अयशस्वी झाले."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"अॅक्टिव्हेट डिव्हाइस प्रशासक अॅप अनइंस्टॉल करू शकत नाही"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> साठी अॅक्टिव्हेट डिव्हाइस प्रशासक अॅप अनइंस्टॉल करू शकत नाही"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"हा अॅप काही वापरकर्ते किंवा प्रोफाईलसाठी आवश्यक आहे आणि इतरांसाठी अनइंस्टॉल केला होता"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"आपल्या प्रोफाईलसाठी हा अॅप आवश्यक आहे आणि अनइंस्टॉल केला जाऊ शकत नाही."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"तुमच्या डिव्हाइस प्रशासकास हे अॅप आवश्यक आहे आणि ते अनइंस्टॉल केले जाऊ शकत नाही."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"डिव्हाइस प्रशासक अॅप्स व्यवस्थापित करा"</string>
+ <string name="manage_users" msgid="3125018886835668847">"वापरकर्त्यांना व्यवस्थापित करा"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> अनइंस्टॉल केला जाऊ शकला नाही."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"पॅकेज चे विश्लेषण करताना समस्या आली."</string>
+ <string name="newPerms" msgid="6039428254474104210">"नवीन"</string>
+ <string name="allPerms" msgid="1024385515840703981">"सर्व"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"गोपनीयता"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"डिव्हाइस अॅक्सेस"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"या अद्यतनास कोणत्याही नवीन परवानग्यांची आवश्यकता नाही."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"नकार द्या"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"अधिक माहिती"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"तरीही नकार द्या"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> पैकी <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला <xliff:g id="ACTION">%2$s</xliff:g> ची अनुमती द्यायची?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला नेहमी <xliff:g id="ACTION">%2$s</xliff:g> ची अनुमती द्यायची का?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"फक्त अॅप वापरत असताना"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"नेहमी"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"नकार द्या आणि पुन्हा विचारू नका"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> अक्षम केल्या"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"सर्व अक्षम केल्या"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"कोणत्याही अक्षम केल्या नाहीत"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"अनुमती द्या"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"अॅप्स"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"अॅप परवानग्या"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"पुन्हा विचारू नका"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"परवानग्या नाहीत"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"अतिरिक्त परवानग्या"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"अॅप माहिती उघडा"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">आणखी <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">आणखी <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"हा अॅप Android च्या जुन्या आवृत्तीसाठी डीझाइन करण्यात आला होता. परवानगी नाकारल्यामुळे तो यापुढे उद्देशाप्रमाणे कार्य करणार नाही."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"अज्ञात क्रिया करा"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> पैकी <xliff:g id="COUNT_0">%1$d</xliff:g> अॅप्सना अनुमती दिली"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"सिस्टम दर्शवा"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"सिस्टीम लपवा"</string>
+ <string name="no_apps" msgid="1965493419005012569">"कोणतेही अॅप्स नाहीत"</string>
+ <string name="location_settings" msgid="1774875730854491297">"स्थान सेटिंग्ज"</string>
+ <string name="location_warning" msgid="8778701356292735971">"या डिव्हाइससाठी <xliff:g id="APP_NAME">%1$s</xliff:g> स्थान सेवांचा प्रदाता आहे. स्थान प्रवेश स्थान सेटिंग्ज वरून सुधारित केला जाऊ शकतो."</string>
+ <string name="system_warning" msgid="7103819124542305179">"तुम्ही ही परवानगी नाकारल्यास, आपल्या डिव्हाइसची मुलभूत वैशिष्ट्ये अपेक्षित असल्याप्रमाणे कदाचित कार्य करू शकणार नाहीत."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"धोरणाद्वारे सक्ती केली"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"धोरणाद्वारे बॅकग्राउंड अॅक्सेस बंद केला आहे"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"धोरणाद्वारे बॅकग्राउंड अॅक्सेस सुरू केला आहे"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"धोरणाद्वारे फोरग्राउंड अॅक्सेस सुरू केला आहे"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"प्रशासनाद्वारे नियंत्रित केलेले"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"नेहमी"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"फक्त अॅप वापरत असताना"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"कधीही नाही"</string>
+ <string name="loading" msgid="7811651799620593731">"लोड करत आहे..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"सर्व परवानग्या"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"अन्य अॅप क्षमता"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"परवानगीची विनंती"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"स्क्रीन ओव्हरले आढळले"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"हे परवानगी सेटिंग बदलण्यासाठी, तुम्हाला सेटिंग्ज > अॅप्स मधून स्क्रीन ओव्हरले बंद करावे लागेल"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"सेटिंग्ज उघडा"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"इंस्टॉल करा/अनइंस्टॉल करा क्रिया Wear वर समर्थित नाहीत."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ला कशामध्ये प्रवेश करण्याची अनुमती द्यावी ते निवडा"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> अपडेट केला गेला आहे. या अॅपला कशामध्ये प्रवेश करण्याची अनुमती द्यावी ते निवडा."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"रद्द करा"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"सुरू ठेवा"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"नवीन परवानग्या"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"वर्तमान परवानग्या"</string>
+ <string name="message_staging" msgid="6151794817691100003">"अॅप प्रारंभाच्या स्थितीत आहे..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"अज्ञात"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"आपल्या सुरक्षिततेसाठी, आपल्या टॅबलेटला या स्रोताकडील अज्ञात अॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"आपल्या सुरक्षिततेसाठी, आपल्या टीव्हीला या स्रोताकडील अज्ञात अॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"आपल्या सुरक्षिततेसाठी, आपल्या फोनला या स्रोताकडील अज्ञात अॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"तुमचा फोन आणि वैयक्तिक डेटा अज्ञात अॅप्समुळे होणार्या अटॅकमुळे अधिक असुरक्षित आहे. हा अॅप इन्स्टॉल करून, तुम्ही सहमती देता की तो वापरल्याने होणार्या तुमच्या फोनच्या कोणत्याही प्रकारच्या नुकसान किंवा डेटा हानीसाठी तुम्ही जबाबदार आहात."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"तुमचा टॅबलेट आणि वैयक्तिक डेटा अज्ञात अॅप्समुळे होणार्या अटॅकमुळे अधिक असुरक्षित आहे. हा अॅप इन्स्टॉल करून, तुम्ही सहमती देता की तो वापरल्याने होणार्या तुमच्या टॅबलेटच्या कोणत्याही प्रकारच्या नुकसान किंवा डेटा हानीसाठी तुम्ही जबाबदार आहात."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"तुमचा टीव्ही आणि वैयक्तिक डेटा अज्ञात अॅप्समुळे होणार्या अटॅकमुळे अधिक असुरक्षित आहे. हा अॅप इन्स्टॉल करून, तुम्ही सहमती देता की तो वापरल्याने होणार्या तुमच्या टीव्हीच्या कोणत्याही प्रकारच्या नुकसान किंवा डेटा हानीसाठी तुम्ही जबाबदार आहात."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"सुरू ठेवा"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"सेटिंग्ज"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"वेअर अॅप्स इन्स्टॉल/अनइन्स्टॉल करणे"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ms-television/strings.xml b/packages/PackageInstaller/res/values-ms-television/strings.xml
new file mode 100644
index 0000000..989aba7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ms-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Tolak dan jangan tanya lagi"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Anda boleh menukar ini nanti dalam Tetapan > Apl"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Tunjukkan apl sistem"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Kebenaran apl"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Kebenaran apl"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Kebenaran <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Kebenaran tambahan"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Kebenaran <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ms-watch/strings.xml b/packages/PackageInstaller/res/values-ms-watch/strings.xml
new file mode 100644
index 0000000..dad185fa
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ms-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Tolak, jangan tanya lagi"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Tunjukkan apl sistem"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Tidak dpt diubah"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ya"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Batal"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml
new file mode 100644
index 0000000..6ab23ac
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ms/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pemasang pakej"</string>
+ <string name="next" msgid="3057143178373252333">"Seterusnya"</string>
+ <string name="install" msgid="5896438203900042068">"Pasang"</string>
+ <string name="done" msgid="3889387558374211719">"Selesai"</string>
+ <string name="cancel" msgid="8360346460165114585">"Batal"</string>
+ <string name="installing" msgid="8613631001631998372">"Memasang..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Memasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikasi dipasang."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Adakah anda mahu memasang aplikasi ini? Aplikasi ini akan mendapat akses kepada:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Adakah anda mahu memasang aplikasi ini? Aplikasi ini tidak memerlukan sebarang akses khas."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Adakah anda mahu memasang kemas kini kepada aplikasi sedia ada ini? Data sedia ada anda tidak akan hilang. Aplikasi yang dikemaskinikan akan mendapat akses kepada:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Adakah anda ingin memasang kemas kini kepada aplikasi terbina dalam ini? Data sedia ada anda tidak akan hilang. Aplikasi yang dikemaskinikan akan mendapat akses kepada:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Adakah anda mahu memasang kemas kini untuk aplikasi sedia ada ini? Data sedia ada anda tidak akan hilang. Hal ini tidak memerlukan sebarang akses khas."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Adakah anda mahu memasang kemas kini untuk aplikasi terbina dalam ini? Data sedia ada anda tidak akan hilang. Hal ini tidak memerlukan sebarang akses khas."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikasi tidak dipasang."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Pakej ini telah disekat daripada dipasang."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Apl tidak dipasang kerana pakej bercanggah dengan pakej yang sedia ada."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Apl tidak dipasang kerana apl tidak serasi dengan tablet anda."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Apl ini tidak serasi dengan TV anda."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Apl tidak dipasang kerana apl tidak serasi dengan telefon anda."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Apl tidak dipasang kerana pakej tidak sah."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasangkan pada tablet anda."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak boleh dipasang pada TV anda."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasangkan pada telefon anda."</string>
+ <string name="launch" msgid="4826921505917605463">"Buka"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Pentadbir anda tidak membenarkan pemasangan apl yang diperoleh daripada sumber yang tidak diketahui"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Apl yang tidak diketahui tidak boleh dipasang oleh pengguna ini"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Pengguna ini tidak dibenarkan memasang apl"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Urus aplikasi"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Kehabisan ruang"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang. Kosongkan sebahagian ruang dan cuba lagi."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikasi tidak ditemui"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikasi tidak ditemui dalam senarai aplikasi yang dipasang."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Tidak dibenarkan"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Pengguna semasa tidak dibenarkan untuk melaksanakan penyahpasangan ini."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Ralat"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Apl tidak dapat dinyapasang."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Nyahpasang aplikasi"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Nyahpasang kemas kini"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> merupakan sebahagian daripada aplikasi berikut:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Adakah anda mahu menyahpasang aplikasi ini?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Adakah anda mahu menyahpasang apl ini untuk "<b>"semua"</b>" pengguna? Aplikasi dan datanya akan dialih keluar daripada "<b>"semua"</b>" pengguna pada peranti."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Adakah anda ingin menyahpasang apl ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar. Tindakan ini melibatkan semua pengguna peranti ini, termasuk mereka yang mempunyai profil kerja."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Penyahpasangan yang sedang berjalan"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Penyahpasangan yang gagal"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Menyahpasang..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Nyahpasang selesai."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> dinyahpasang"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Nyahpasang tidak berjaya."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Tidak berjaya menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Tidak dapat menyahpasang apl pentadbir peranti yang aktif"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Tidak dapat menyahpasang apl pentadbir peranti yang aktif untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Apl ini diperlukan untuk sesetengah pengguna atau profil dan telah dinyahpasang untuk yang lain"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Apl ini diperlukan untuk profil anda dan tidak boleh dinyahpasang."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Apl ini diperlukan oleh pentadbir peranti anda dan tidak boleh dinyahpasang."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Urus apl pentadbir peranti"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Urus pengguna"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dinyahpasang."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Terdapat masalah menghuraikan pakej."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Baharu"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Semua"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privasi"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Akses Peranti"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Kemas kini ini tidak memerlukan kebenaran baharu."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Tolak"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Maklumat lanjut"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tolak juga"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> daripada <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Sentiasa benarkan <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Hanya semasa menggunakan apl"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Sentiasa"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Tolak dan jangan tanya lagi"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> dilumpuhkan"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"semua dilumpuhkan"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"tiada apa-apa yang dilumpuhkan"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Benarkan"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apl"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Kebenaran apl"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Jangan tanya lagi"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Tiada kebenaran"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Kebenaran tambahan"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Buka maklumat apl"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> lagi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> lagi</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Apl ini direka bentuk untuk versi Android yang lebih lama. Tindakan menafikan kebenaran boleh menyebabkannya tidak berfungsi seperti yang dimaksudkan lagi."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"laksanakan tindakan yang tidak diketahui"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> daripada <xliff:g id="COUNT_1">%2$d</xliff:g> apl dibenarkan"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Tunjukkan sistem"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Sembunyikan sistem"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Tiada apl"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Tetapan Lokasi"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ialah pembekal perkhidmatan lokasi untuk peranti ini. Akses lokasi boleh diubah suai daripada tetapan lokasi."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Jika anda tolak kebenaran ini, ciri asas peranti anda mungkin tidak berfungsi seperti yang dimaksudkan lagi."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Dikuatkuasakan oleh dasar"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Akses latar belakang dilumpuhkan oleh dasar"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Akses latar belakang didayakan oleh dasar"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Akses latar depan didayakan oleh dasar"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Dikawal oleh pentadbir"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Sentiasa"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Hanya semasa menggunakan apl"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Jangan sekali-kali"</string>
+ <string name="loading" msgid="7811651799620593731">"Memuatkan…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Semua kebenaran"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Keupayaan apl yang lain"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Permintaan kebenaran"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Tindanan skrin dikesan"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Untuk menukar tetapan kebenaran ini, anda perlu mematikan tindanan skrin daripada Tetapan > Apl terlebih dahulu"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Buka tetapan"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Tindakan pasang/nyahpasang tidak disokong pada Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Pilih perkara yang boleh diakses oleh <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> telah dikemas kini. Pilih perkara yang boleh diakses oleh apl ini."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Batal"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Teruskan"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Kebenaran baharu"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Kebenaran semasa"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Pemeringkatan apl…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Tidak diketahui"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Untuk keselamatan, tablet anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Untuk keselamatan, TV anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Untuk keselamatan, telefon anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada telefon anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tablet dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada tablet anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada TV anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Teruskan"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Tetapan"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Memasang/menyahpasang apl wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-my-television/strings.xml b/packages/PackageInstaller/res/values-my-television/strings.xml
new file mode 100644
index 0000000..b802f59
--- /dev/null
+++ b/packages/PackageInstaller/res/values-my-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"ငြင်းဆိုပြီး ထပ်မံ မမေးပါနှင့်"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"နောင်တွင် ဤသည်အား ဆက်တင်များ > အက်ပ်များတွင် ပြင်နိုင်၏"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"စနစ်အပ်ဖ်များ ပြသရန်"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"အက်ပ်ခွင့်ပြုချက်များ"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"အက်ပ်ခွင့်ပြုချက်များ"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> ခွင့်ပြုချက်များ"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"အပိုဆောင်း ခွင့်ပြုချက်များ"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> ခွင့်ပြုချက်များ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-my-watch/strings.xml b/packages/PackageInstaller/res/values-my-watch/strings.xml
new file mode 100644
index 0000000..21283c0
--- /dev/null
+++ b/packages/PackageInstaller/res/values-my-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ငြင်းပယ်သည်၊ ထပ်မမေးပါနှင့်"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"စနစ်အပ်ဖ်များ ပြသရန်"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ပြောင်းလဲ မရနိုင်ပါ"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Yes"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"မလုပ်တော့"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml
new file mode 100644
index 0000000..02199c3
--- /dev/null
+++ b/packages/PackageInstaller/res/values-my/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Package ထည့်သွင်းခြင်း"</string>
+ <string name="next" msgid="3057143178373252333">"ရှေ့သို့"</string>
+ <string name="install" msgid="5896438203900042068">"ထည့်သွင်းပါ"</string>
+ <string name="done" msgid="3889387558374211719">"ပြီးပါပြီ"</string>
+ <string name="cancel" msgid="8360346460165114585">"မလုပ်တော့"</string>
+ <string name="installing" msgid="8613631001631998372">"ထည့်သွင်းနေပါသည်"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ထည့်သွင်းနေသည်…"</string>
+ <string name="install_done" msgid="3682715442154357097">"အက်ပ်ထည့်သွင်းပြီး"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ဤအပလီကေးရှင်းကို ထည့်သွင်းပါမလား။ ဤအပလီကေးရှင်း သုံးစွဲခွင့်ရှိမှာ ကတော့:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ဤအပလီကေးရှင်းကို ထည့်သွင်းပါမလား။ အထူးတလည် သုံးခွင့် မလိုအပ်ပါ"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"လက်ရှိ ရှိပြီးသား အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။ ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အပ်ဒိတ်လုပ်လိုက်သော အပလီကေးရှင်းသုံးစွဲခွင့်ရှိမှာ များကတော့-"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"အဆင့်သင့် ပါလာသော အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။ ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အပ်ဒိတ်လုပ်လိုက်သော အပလီကေးရှင်း သုံးစွဲခွင့်ရှိမှာ များကတော့ -"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"လက်ရှိ ရှိပြီးသား အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။ ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အထူးတလည် သုံးခွင့် မလိုအပ်ပါ"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"အဆင့်သင့် ပါလာသော အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။ ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အထူးတလည် သုံးခွင့် မလိုအပ်ပါ"</string>
+ <string name="install_failed" msgid="6579998651498970899">"အက်ပ်မထည့်သွင်းရသေးပါ"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ပက်ကေ့ထည့်သွင်းခြင်းကို ပိတ်ဆို့ထားသည်။"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် လက်ရှိပက်ကေ့ဂျ်နှင့် တိုက်နေသည်။"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"အက်ပ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် သင့်တက်ဘလက်နှင့် ကိုက်ညီမှုမရှိပါ။"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ဤ အက်ပ်သည် သင့်တီဗွီနှင့် တွဲဖက်သုံးမရပါ။"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"အက်ပ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် သင့်ဖုန်းနှင့် ကိုက်ညီမှုမရှိပါ။"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် မှန်ကန်မှုမရှိပုံပေါ်သည်။"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို သင့်တက်ဘလက်တွင် ထည့်သွင်းလို့ မရနိုင်ပါ"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"သင့်တီဗွီတွင် <xliff:g id="APP_NAME">%1$s</xliff:g> အား မတပ်ဆင်နိုင်ပါ။"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို သင့်ဖုန်းတွင် ထည့်သွင်းလို့ မရနိုင်ပါ"</string>
+ <string name="launch" msgid="4826921505917605463">"ဖွင့်သည်"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"သင်၏ စီမံခန့်ခွဲသူက ရင်းမြစ်မသိသော အက်ပ်များကို ထည့်သွင်းခွင့်မပြုပါ"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"အရင်းအမြစ်မသိသော အက်ပ်များကို ဤအသုံးပြုသူက ထည့်သွင်းခွင့်မရှိပါ"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ဤအသုံးပြုသူသည် အက်ပ်များကို ထည့်သွင်းခွင့်မရှိပါ"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"အပလီကေးရှင်းများအား ထိန်းသိမ်းခြင်း"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"နေရာလွတ်မရှိပါ"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ထည့်သွင်းလို့ မရနိုင်ပါ။ နေရာအပိုရအောင် ရှင်းလင်းပြီး ပြန်ကြိုးစားပါ"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"အက်ပ်အားမတွေ့ပါ"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ထည့်သွင်းထားသော အပလီကေးရှင်းထဲတွင် ဤအပလီကေးရှင်း မတွေ့ရှိပါ"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ခွင့်ပြုမထားပါ"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ဤဖယ်ရှားမှုပြုလုပ်ရန် လက်ရှိအသုံးပြုသူအား ခွင့်ပြုမထားပါ။"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"အမှားအယွင်း"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"အက်ပ်ကို ဖယ်ရှား၍မရနိုင်ပါ။"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"အပလီကေးရှင်းကို ဖယ်ရှားပါ"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"အပ်ဒိတ်လုပ်ထားခြင်းကို ပြန်ထုတ်ပါ"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ကတော့ အောက်ပါ အက်ပ်၏အစိတ်အပိုင်း တစ်ခု ဖြစ်ပါသည်:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ဤအပလီကေးရှင်းကို သင်ဖယ်ရှားချင်ပါသလား"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ဤအပလီကေးရှင်းကို အသုံးပြုသူ"<b>" အားလုံး"</b>" အတွက် ဖယ်ရှားချင်ပါသလား? ဤအပလီကေးရှင်း နှင့် သက်ဆိုင်ရာ အချက်အလက်များ အားလုံးကို "<b>" မှ အားလုံးသော "</b>" စက်အသုံးပြုသူတွေအတွက် ဖယ်ရှားပစ်ပါလိမ့်မည်"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"သင်သည် အသုံးပြုသူ <xliff:g id="USERNAME">%1$s</xliff:g> အတွက် ဒီအကောင့်ကို ဖြုတ်ပစ်လိုပါသလား?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ဤအက်ပ်ကို စက်ရုံထုတ်ဗားရှင်းဖြင့် အစားထိုးမလား။ ဒေတာများအားလုံးကို ဖယ်ရှားလိုက်ပါမည်။"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ဤအက်ပ်ကို စက်ရုံထုတ်ဗားရှင်းဖြင့် အစားထိုးမလား။ ဒေတာများအားလုံးကို ဖယ်ရှားလိုက်ပါမည်။ ၎င်းသည် အလုပ်ပရိုဖိုင်ဖြင့်သုံးသူများအပါအဝင် အသုံးပြုသူများအားလုံးကို အကျိုးသက်ရောက်စေပါလိမ့်မည်။"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ပရိုဂရမ်ကို ဖယ်ရှားနေပါသည်"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ပရိုဂရမ်ကို ဖယ်ရှားခြင်းမအောင်မြင်ပါ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"ဖယ်ထုတ်သည်"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားနေပါသည်…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"ဖယ်ရှားခြင်း ပြီးပါပြီ"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားလိုက်ပါပြီ"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ဖယ်ရှားမှု မအောင်မြင်ပါ"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားခြင်း မအောင်မြင်ပါ။"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ဖွင့်ထားသော စက်ပစ္စည်းကို စီမံခန့်ခွဲရန်အက်ပ်အား ဖယ်ရှား၍မရပါ"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> အတွက် ဖွင့်ထားသော စက်ပစ္စည်းကို စီမံခန့်ခွဲရန် အက်ပ်အား ဖယ်ရှား၍မရပါ။"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"အချို့အသုံးပြုသူများ သို့မဟုတ် ပရိုဖိုင်များအတွက် ဤအက်ပ်ကို လိုအပ်သော်လည်း အချို့သူများအတွက် ဖြုတ်ထားပါသည်"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"သင့်ပရိုဖိုင်အတွက် ဤအက်ပ်ကိုလိုအပ်ပြီး ဖြုတ်၍မရပါ။"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ဒီအက်ပ်မှာ သင်၏ ကိရိယာ စီမံအုပ်ချုပ်သူက လိုအပ်သောကြောင့် ဖြုတ်၍ မရနိုင်ပါ။"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"စက်ပစ္စည်းကို စီမံခန့်ခွဲရန် အက်ပ်များအား စီမံရန်"</string>
+ <string name="manage_users" msgid="3125018886835668847">"အသုံးပြုသူများအား စီမံခန့်ခွဲပါ"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ဖယ်ရှားလို့ မရပါ"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ဒေတာအချက်အလက်အစုအားဖတ်ရှုစဉ် ပြသနာ တစ်ခု ဖြစ်ပေါ်ပါသည်"</string>
+ <string name="newPerms" msgid="6039428254474104210">"အသစ်"</string>
+ <string name="allPerms" msgid="1024385515840703981">"အားလုံး"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"လုံခြုံမှု"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"စက်ပစ္စည်း အသုံးပြုခွင့်"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ဤအပ်ဒိတ်အတွက် ခွင့်ပြုချက်အသစ် မလိုအပ်ပါ"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ငြင်းပယ်သည်"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"အခြားအချက်အလက်များ"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"မည်သို့ပင်ဖြစ်စေ ငြင်းပယ်ပါ"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို <xliff:g id="ACTION">%2$s</xliff:g> ရန်ခွင့်ပြုမလား။"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ကို <xliff:g id="ACTION">%2$s</xliff:g> ရန် အမြဲခွင့်ပြုသလား။"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"အက်ပ်အသုံးပြုစဉ်သာ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"အမြဲတမ်း"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ငြင်းဆိုသည်၊ ထပ်မမေးပါနှင့်"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ခု ပိတ်ထားသည်"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"အားလုံးပိတ်ထားသည်"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"တစ်ခုမျှ ပိတ်မထားပါ"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ခွင့်ပြုသည်"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"အက်ပ်များ"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"အက်ပ်ခွင့်ပြုချက်များ"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"နောက်ထပ်မမေးပါနှင့်"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ခွင့်ပြုချက်မရှိ"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"ထပ်တိုး ခွင့်ပြုချက်များ"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"အက်ပ်အချက်အလက် ဖွင့်ရန်"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"> နောက်ထပ် <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one"> နောက်ထပ် <xliff:g id="COUNT_0">%1$d</xliff:g> </item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ဤအက်ပ် အား Android ၏ ဗားရှင်းဟောင်းအတွက် ပုံဆွဲရေးဆွဲထား၏။ ခွင့်ပြုချက်ပေးရန် ငြင်းဆိုပါက ရည်ရွယ်ထားသကဲ့သို့ ဆောင်ရွက်လိမ့်မည် မဟုတ်ပါ။"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"အမျိုးအမည်မသိ ဆောင်ရွက်ချက်တစ်ခု လုပ်ရန်"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"အက်ပ် <xliff:g id="COUNT_1">%2$d</xliff:g> မှ <xliff:g id="COUNT_0">%1$d</xliff:g> ခု ခွင့်ပြုသည်"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"စနစ်ကိုပြသရန်"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"စနစ်ကို ဖျောက်မည်"</string>
+ <string name="no_apps" msgid="1965493419005012569">"အက်ပ် မရှိပါ"</string>
+ <string name="location_settings" msgid="1774875730854491297">"တည်နေရာ ဆက်တင်များ"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် ဤစက်ပစ္စည်းအတွက် တည်နေရာ ဝန်ဆောင်မှုများ ထုတ်ပေးသူဖြစ်သည်။ တည်နေရာ အသုံးပြုမှုကို တည်နေရာချိန်ညှိမှုများတွင် ပြုပြင်နိုင်သည်။"</string>
+ <string name="system_warning" msgid="7103819124542305179">"ဤခွင့်ပြုချက်အား သင် ငြင်းဆိုပါက၊ သင့်စက်ကိရိယာ၏ အခြေခံလုပ်ဆောင်ချက်များသည် ရည်ရွယ်ထားသကဲ့သို့ အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"မူဝါဒအားဖြင့်ပြဌာန်းရန်"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"နောက်ခံတွင်ဝင်သုံးခွင့်ကို မူဝါဒက ပိတ်ထားသည်"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"နောက်ခံတွင်ဝင်သုံးခွင့်ကို မူဝါဒက ဖွင့်ထားသည်"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"မျက်နှာစာတွင်ဝင်သုံးခွင့်ကို မူဝါဒက ဖွင့်ထားသည်"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"စီမံခန့်ခွဲသူက ထိန်းချုပ်ထားသည်"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"အမြဲတမ်း"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"အက်ပ်အသုံးပြုစဉ်သာ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ဘယ်တော့မှ"</string>
+ <string name="loading" msgid="7811651799620593731">"တင်နေ…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"ခွင့်ပြုချက်များ အားလုံး"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"အခြားအပ်ဖ်၏ စွမ်းရည်များ"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"ခွင့်ပြုချက် တောင်းခံမှု"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"မျက်နှာပြင် ထပ်ပေးမှုကို ရှာတွေ့ခဲ့"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ဒီခွင့်ပြုချက် ဆက်တင်ကို ပြောင်းရန်၊ သင်ဟာ ဦးစွာ ဆက်တင်များ > အက်ပ်များ ထဲတွင် မျက်နှာပြင် ထပ်ပေးမှုကို ပိတ်လိုက်ရန် လိုမယ်"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ဆက်တင်းများ ဖွင့်ရန်"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ပေါ်တွင် ထည့်သွင်းခြင်း/ဖြုတ်ခြင်းများကို ပံ့ပိုးမထားပါ။"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"&It;b7gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&It;/b> က အသုံးပြုခွင့်ရမည့် အရာတို့ကို ရွေးပါ"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"&It;b><xliff:g id="APP_NAME">%1$s</xliff:g>&It;/b> ကို အပ်ဒိတ်လုပ်ပြီးပါပြီ။ ဤအက်ပ်က အသုံးပြုခွင့်ရမည့်အရာတို့ကို ရွေးပါ။"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"မလုပ်တော့"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ဆက်လုပ်ရန်"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"ခွင့်ပြုချက် အသစ်များ"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"လက်ရှိ ခွင့်ပြုချက်များ"</string>
+ <string name="message_staging" msgid="6151794817691100003">"အက်ပ်ကို ပြင်ဆင်နေသည်…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"အမျိုးအမည်မသိ"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏တက်ဘလက်တွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏တီဗီတွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏ဖုန်းတွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"သင်၏ဖုန်းနှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော ဖုန်းပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"သင်၏ တက်ဘလက်နှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော တက်ဘလက်ပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"သင်၏ TV နှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော TV ပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ဆက်လုပ်ရန်"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ဆက်တင်များ"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"wear အက်ပ်ကိုထည့်သွင်းခြင်း/ဖယ်ရှားခြင်း"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-nb-television/strings.xml b/packages/PackageInstaller/res/values-nb-television/strings.xml
new file mode 100644
index 0000000..57f6a21
--- /dev/null
+++ b/packages/PackageInstaller/res/values-nb-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Avvis, og ikke spør igjen"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Du kan endre dette senere i Innstillinger > Apper"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Vis systemapper"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Apptillatelser"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Apptillatelser"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Tillatelser for <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Flere tillatelser"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Tillatelser for <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-nb-watch/strings.xml b/packages/PackageInstaller/res/values-nb-watch/strings.xml
new file mode 100644
index 0000000..332a8fe
--- /dev/null
+++ b/packages/PackageInstaller/res/values-nb-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Avvis, ikke spør igjen"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Vis systemapper"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Kan ikke endres"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ja"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Avbryt"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml
new file mode 100644
index 0000000..3ff3de4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-nb/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pakkeinstallasjon"</string>
+ <string name="next" msgid="3057143178373252333">"Neste"</string>
+ <string name="install" msgid="5896438203900042068">"Installer"</string>
+ <string name="done" msgid="3889387558374211719">"Ferdig"</string>
+ <string name="cancel" msgid="8360346460165114585">"Avbryt"</string>
+ <string name="installing" msgid="8613631001631998372">"Installerer…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Installerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+ <string name="install_done" msgid="3682715442154357097">"Appen er installert."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Ønsker du å installere denne appen? Den får tilgang til følgende:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ønsker du å installere denne appen? Den krever ingen spesiell tilgang."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Ønsker du å installere en oppdatering for denne eksisterende appen? Du mister ingen eksisterende data. Den oppdaterte appen får tilgangen spesifisert nedenfor."</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ønsker du å installere en oppdatering for denne innebygde appen? Du mister ingen eksisterende data. Den oppdaterte appen får tilgangen spesifisert nedenfor."</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vil du installere en oppdatering av denne eksisterende appen? De eksisterende dataene dine går ikke tapt. Dette krever ingen spesiell tilgang."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vil du installere en oppdatering av denne innebygde appen? De eksisterende dataene dine går ikke tapt. Dette krever ingen spesiell tilgang."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Appen ble ikke installert."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Pakken er blokkert fra å bli installert."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Appen ble ikke installert fordi pakken er i konflikt med en eksisterende pakke."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Appen ble ikke installert fordi appen ikke er kompatibel med nettbrettet ditt."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Denne appen er ikke kompatibel med TV-en din."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Appen ble ikke installert fordi appen ikke er kompatibel med telefonen din."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Appen ble ikke installert fordi pakken ser ut til å være ugyldig."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på nettbrettet ditt."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på TV-en."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på telefonen din."</string>
+ <string name="launch" msgid="4826921505917605463">"Åpne"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratoren din tillater ikke installering av apper som er hentet fra ukjente kilder"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ukjente apper kan ikke installeres av denne brukeren"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Brukeren har ikke tillatelse til å installere apper"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Administrer apper"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Tom for plass"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigjør plass og prøv på nytt."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Appen ble ikke funnet"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Finner ikke appen i listen over installerte apper."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ikke tillatt"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Denne brukeren har ikke tillatelse til å utføre denne avinstalleringen."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Feil"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Kunne ikke avinstallere appen."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Avinstaller appen"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Avinstaller oppdateringen"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er del av følgende app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Vil du avinstallere denne appen?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vil du avinstallere denne appen for "<b>"alle"</b>" brukere? Appen og tilhørende data blir fjernet fra "<b>"alle"</b>" brukere på enheten."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ønsker du å avinstallere denne appen for brukeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes. Dette påvirker alle som bruker denne enheten – også personer med jobbprofiler."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Avinstalleringer som er i gang"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislykkede avinstalleringer"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Avinstallerer…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Avinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Avinstalleringen er fullført."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Avinstallerte <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Avinstalleringen mislyktes."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Kunne ikke avinstallere <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Kan ikke avinstallere den aktive appen for enhetsadministrator"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kan ikke avinstallere den aktive appen for enhetsadministrator for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Appen er nødvendig for noen brukere eller profiler, og den er avinstallert for andre"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Denne appen er nødvendig for profilen din og kan ikke avinstalleres."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Denne appen kreves av enhetsadministratoren din og kan ikke avinstalleres."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Administrer apper for enhetsadministrator"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Administrer brukere"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Det oppsto et problem med analysen av pakken."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nye"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Personvern"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Enhetstilgang"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Denne oppdateringen krever ingen nye tillatelser."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Ikke tillat"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Finn ut mer"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Avvis likevel"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> av <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Vil du gi <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> tillatelse til å <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vil du alltid tillate at <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> kan <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Bare når appen brukes"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Alltid"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Avvis, og ikke spør igjen"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> er slått av"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"alt er slått av"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ingen er slått av"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Tillat"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apper"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Apptillatelser"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ikke spør igjen"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Ingen tillatelser"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Flere tillatelser"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Åpne info om appen"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> til</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> til</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Denne appen er designet for en eldre versjon av Android. Hvis du nekter å gi tillatelse, kan det føre til at den ikke lenger fungerer etter hensikten."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"utfør en ukjent handling"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> av <xliff:g id="COUNT_1">%2$d</xliff:g> apper er tillatt"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Vis systemapper"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Skjul systemet"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Ingen apper"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Posisjonsinnstillinger"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> er en leverandør av posisjonstjenester for denne enheten. Tilgang til posisjon kan endres fra posisjonsinnstillingene."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Hvis du ikke gir denne tillatelsen, kan grunnleggende funksjoner på enheten slutte å fungere som de skal."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Påkrevd ifølge retningslinjene"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Bakgrunnstilgang er slått av pga. retningslinjene"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Bakgrunnstilgang er slått på pga. retningslinjene"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Forgrunnstilgang er slått på pga. retningslinjene"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrollert av administratoren"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Alltid"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Bare når appen brukes"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Aldri"</string>
+ <string name="loading" msgid="7811651799620593731">"Laster inn …"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Alle tillatelser"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Andre appfunksjoner"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Forespørsel om tillatelse"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Skjermoverlegg oppdaget"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"For å endre denne tillatelsesinnstilingen må du først slå av skjermoverlegget fra Innstillinger > Apper"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Åpne innstillingene"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Handlinger for å installere og avinstallere er ikke støttet på Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Velg hva du vil gi <xliff:g id="APP_NAME">%1$s</xliff:g> tilgang til"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<xliff:g id="APP_NAME">%1$s</xliff:g> er oppdatert. Velg hva du vil gi denne appen tilgang til."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Avbryt"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Fortsett"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nye tillatelser"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Gjeldende tillatelser"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Setter opp appen …"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Ukjent"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Nettbrettet ditt har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"TV-en din har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Telefonen din har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonen din og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på telefonen eller tap av data bruk av appen forårsaker."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Nettbrettet ditt og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på nettbrettet eller tap av data bruk av appen forårsaker."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV-en din og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på TV-en eller tap av data bruk av appen forårsaker."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Fortsett"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Innstillinger"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Installerer/avinstallerer wear-apper"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ne-television/strings.xml b/packages/PackageInstaller/res/values-ne-television/strings.xml
new file mode 100644
index 0000000..d6e908c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ne-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"अस्वीकृत गर्नुहोस् र फेरि नसोध्नुहोस्"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"तपाईं यसलाई पछि सेटिङ > अनुप्रयोगमा बदल्न सक्नु हुन्छ"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"प्रणाली अनुप्रयोगहरू देखाउनुहोस्"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"अनुप्रयोग सम्बन्धी अनुमतिहरू"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"अनुप्रयोग सम्बन्धी अनुमतिहरू"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> सम्बन्धी अनुमतिहरू"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"अतिरिक्त अनुमतिहरू"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> सम्बन्धी अनुमतिहरू"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ne-watch/strings.xml b/packages/PackageInstaller/res/values-ne-watch/strings.xml
new file mode 100644
index 0000000..ffcc2f7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ne-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"अस्वीकार गर्नुहोस्, फेरि नसोध्नुहोस्"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"प्रणाली अनुप्रयोगहरू देखाउनुहोस्"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"परिवर्तन गर्न सकिँदैन"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"हो"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"रद्द गर्नुहोस्"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
new file mode 100644
index 0000000..b2dea8f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"प्याकेज स्थापनकर्ता"</string>
+ <string name="next" msgid="3057143178373252333">"अर्को"</string>
+ <string name="install" msgid="5896438203900042068">"स्थापना गर्नुहोस्"</string>
+ <string name="done" msgid="3889387558374211719">"भयो"</string>
+ <string name="cancel" msgid="8360346460165114585">"रद्द गर्नुहोस्"</string>
+ <string name="installing" msgid="8613631001631998372">"स्थापित हुँदै…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> स्थापना गर्दै…"</string>
+ <string name="install_done" msgid="3682715442154357097">"अनुप्रयोग स्थापना भयो।"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"के तपाईं यो अनुप्रयोग स्थापन गर्न चाहनु हुन्छ? यसले पहुँच प्राप्त गर्ने छ:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"के तपाईं यस अनुप्रयोगलाई जडान गर्न चाहनु हुन्छ? यसको लागि कुनै विशेष पहुँचको आवश्यकता पर्दैन।"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"के तपाईँसँग अहिले भईरहेको अनुप्रयोगको एक अपडेट लाई स्थापित गर्न चाहानुहुन्छ? तपाईँको अहिलेको डेटा हराउने छैन। अपडेट भएको अनुप्रयोग पहुँच पाउनेछ मा:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"के तपाईं यस पूर्व-निर्मित अनुप्रयोगमा अपडेट स्थापित गर्न चाहनु हुन्छ? तपाईंको रहेको डेटा हराउने छैन। अपडेट गरिएको अनुप्रयोगले पहुँच पाउने छ:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"के तपाईँसँग अहिले भइरहेको अनुप्रयोगको एउटा अपडेटलाई स्थापित गर्न चाहनु हुन्छ? तपाईँको अहिलेको डेटा हराउने छैन। यसलाई कुनै विशेष पहुँचको आवश्यकता छैन।"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"के तपाईं यस जोडिएको अनुप्रयोगको एउटा अपडेटलाई स्थापित गर्न चाहनुहुन्छ? तपाईंको अहिलेको डेटा हराउने छैन। यसलाई कुनै विशेष पहुँचको आवश्यकता छैन।"</string>
+ <string name="install_failed" msgid="6579998651498970899">"अनुप्रयोग स्थापना भएन।"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"यो प्याकेज स्थापना हुनबाट अवरुद्ध भएको थियो।"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग विद्यमान प्याकेजसँग मेल खाँदैन।"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको ट्याब्लेटसँग मिल्दो छैन।"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"यो अनुप्रयोग तपाईँको TV को लागि उपयुक्त छैन।"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको फोनसँग मिल्दो छैन।"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग अमान्य जस्तो देखिन्छ।"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईँको ट्याब्लेटमा स्थापित हुन सकेन।"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"तपाईँको TVमा<xliff:g id="APP_NAME">%1$s</xliff:g>स्थापना गर्न सकिएन।"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"तपाईँको फोनमा <xliff:g id="APP_NAME">%1$s</xliff:g> जडान हुन सकेन।"</string>
+ <string name="launch" msgid="4826921505917605463">"खोल्नुहोस्"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"तपाईंका प्रशासकले अज्ञात स्रोतहरूबाट प्राप्त अनुप्रयोगहरूलाई स्थापना गर्ने अनुमति दिनुहुन्न"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"यस प्रयोगकर्ताले अज्ञात अनुप्रयोगहरू स्थापना गर्न सक्नुहुन्न"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"यो प्रयोगकर्तालाई अनुप्रयोगहरूको स्थापना गर्ने अनुमति छैन"</string>
+ <string name="ok" msgid="3468756155452870475">"ठिक छ"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"अनुप्रयोगहरूको व्यवस्थापन गर्नुहोस्"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ठाउँभन्दा बाहिर"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> स्थापन गर्न सकिएन। केही ठाउँ खाली गर्नुहोस् र फेरि कोसिस गर्नुहोस्"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"अनुप्रयोग फेला परेन"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"स्थापना भएको अनुप्रयोगहरू सूचीमा अनुप्रयोग फेला परेको थिएन।"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"अनुमति छैन"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"हालको प्रयोगकर्तालाई यो स्थापना रद्द गर्ने कार्य गर्ने अनुमति छैन।"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"त्रुटि"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"अनुप्रयोगको स्थापना रद्द गर्न सकिएन।"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"अनुप्रयोग अस्थापना गर्नुहोस्"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"परिस्कारहरू अस्थापना गर्नुहोस्"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्न अनुप्रयोगको अंश हो:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"के तपाईं यो अनुप्रयोग अस्थापना गर्न चाहनु हुन्छ?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"के तपाईं यो अनुप्रयोग "<b>"सबै"</b>" प्रयोगकर्ताहरूको लागि स्थापना रद्द गर्न चाहनु हुन्छ? अनुप्रयोग र यसको डेटा "<b>"सबै"</b>" प्रयोगकर्ताहरूबाट उपकरणमा हटाइने छ।"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"के तपाईं प्रयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> को लागि यो अनुप्रयोग स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइनेछ।"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइनेछ। यसले यस यन्त्रका कार्य प्रोफाइल भएका लगायत सबै प्रयोगकर्ताहरूमा असर पार्छ।"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"चलिरहेका स्थापना रद्द गर्ने कार्यहरू"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"असफल भएका स्थापना रद्द गर्ने कार्यहरू"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"अस्थापना गर्दै..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्दै…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"स्थापना रद्द गर्न सकियो।"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गरियो"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"अस्थापना गर्न असफल"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्ने कार्य असफल भयो।"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> को यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"अन्य प्रयोगकर्ताहरूका लागि यस अनु्प्रयोगको स्थापना रद्द गरे पनि केही प्रयोगकर्ता वा प्रोफाइलहरूलाई यसको आवश्यकता पर्दछ"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"यो अनुप्रयोग तपाईँको प्रोफाइलका लागि आवश्यक छ र यसको स्थापनालाई रद्द गर्न सकिँदैन।"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"यो अनुप्रयोग तपाईँको उपकरण प्रशासकलाई आवश्यक छ र स्थापना रद्द गर्न सकिँदैन।"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"यन्त्रका प्रशासकीय अनुप्रयोगहरूको व्यवस्थापन गर्नुहोस्"</string>
+ <string name="manage_users" msgid="3125018886835668847">"प्रयोगकर्ताहरूलाई व्यवस्थापन गर्नुहोस्"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना रद्द गर्न सकिँदैन।"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"प्याकेजलाई पार्सिङ गर्दा एउटा समस्या आयो।"</string>
+ <string name="newPerms" msgid="6039428254474104210">"नयाँ"</string>
+ <string name="allPerms" msgid="1024385515840703981">"सबै"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"गोपनीयता"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"उपकरण पहुँच"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"यस अपडेटलाई नयाँ अनुमति आवश्यक पर्दैन।"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"अस्वीकार गर्नुहोस्"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"थप जानकारी"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"जे भए पनि अस्वीकार गर्नुहोस्"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> को <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई <xliff:g id="ACTION">%2$s</xliff:g> गर्न अनुमति दिने हो?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई सधैँ <xliff:g id="ACTION">%2$s</xliff:g> गर्ने अनुमति दिने हो?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"अनुप्रयोग प्रयोग गर्दा मात्र"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"सधैँ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"अस्वीकार गरी फेरि नसोध्नुहोस्"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> अनुमतिहरूलाई असक्षम पारिएको छ"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"सबै अनुमतिहरूलाई असक्षम पारिएको छ"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"कुनै पनि अनुमतिलाई असक्षम पारिएको छैन"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"अनुमति दिनुहोस्"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"अनुप्रयोगहरू"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"अनुप्रयोग अनुमतिहरू"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"फेरि नसोध्नुहोस्"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"कुनै अनुमतिहरू छैनन्"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"अतिरिक्त अनुमतिहरू"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"अनुप्रयोगसम्बन्धी जानकारी खोल्नुहोस्"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> थप</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> थप</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"यो अनुप्रयोग Android को पुरानो संस्करणका लागि डिजाइन गरिएको थियो। अनुमति अस्वीकृत गर्नाले यसले चाहिएको जस्तो कार्य नगर्न सक्छ।"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"एउटा अज्ञात कार्य गर्नुहोस्"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> को <xliff:g id="COUNT_0">%1$d</xliff:g> अनुप्रयोगहरूलाई अनुमति छ"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"प्रणाली देखाउनुहोस्"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"प्रणाली लुकाउनुहोस्"</string>
+ <string name="no_apps" msgid="1965493419005012569">"कुनै अनुप्रयोगहरू छैनन्।"</string>
+ <string name="location_settings" msgid="1774875730854491297">"स्थान सेटिङहरू"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> यो यन्त्रका लागि स्थान सेवाहरूको एउटा प्रदायक हो। स्थान पहुँच स्थान सेटिङहरूबाट परिमार्जन गर्न सकिन्छ।"</string>
+ <string name="system_warning" msgid="7103819124542305179">"तपाईँले यो अनुमति अस्वीकार गर्नुभयो भने तपाईँको यन्त्रका मूल विशेषताहरू अब चाहेअनुसार कार्य नगर्न सक्छ।"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"नीतिद्वारा लागू गरियो"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"नीतिले पृष्ठभूमिको पहुँचलाई असक्षम पारेको छ"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"नीतिले पृष्ठभूमिको पहुँचलाई सक्षम पारेको छ"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"नीतिले अग्रभूमिको पहुँचलाई सक्षम पारेको छ"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"प्रशासकले नियन्त्रण गर्नुभएको"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"सधैँ"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"अनुप्रयोग प्रयोग गर्दा"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"कहिल्यै होइन"</string>
+ <string name="loading" msgid="7811651799620593731">"लोड हुँदैछ..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"सबै अनुमतिहरू"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"अन्य अनुप्रयोग क्षमताहरू"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"अनुमति अनुरोध"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"स्क्रिन ओभरले पत्ता लाग्यो"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"यो अनुमति सेटिङ परिवर्तन गर्न, तपाईँले पहिला सेटिङ अनुप्रयोगबाट स्क्रिन ओभरले बन्द गर्नु पर्दछ।"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"सेटिङहरू खोल्नुहोस्"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear मा स्थापना/स्थापना रद्द गर्ने कारबाहीहरू समर्थित छैनन्।"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई के माथि पहुँच राख्न दिने भन्ने कुरा छनौट गर्नुहोस्"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> लाई अद्यावधिक गरिएको छ। यस अनुप्रयोगलाई के माथि पहुँच राख्न दिने भन्ने कुरा छनौट गर्नुहोस्।"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"रद्द गर्नुहोस्"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"जारी राख्नुहोस्"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"नयाँ अनुमतिहरू"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"वर्तमान अनुमतिहरू"</string>
+ <string name="message_staging" msgid="6151794817691100003">"अनुप्रयोगलाई तयार पार्दै…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"अज्ञात"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"तपाईंको सुरक्षाको लागि, तपाईंको ट्याब्लेटलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"तपाईंको सुरक्षाको लागि, तपाईंको TV लाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"तपाईंको सुरक्षाको लागि, तपाईंको फोनलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"तपाईंको फोन र व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको फोनलाई हुनसक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुनुहुन्छ भन्ने कुरामा सहमत हुनुहुन्छ।"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"तपाईंको ट्याब्लेट र व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको ट्याब्लेटलाई हुनसक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुनुहुन्छ भन्ने कुरामा सहमत हुनुहुन्छ।"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"तपाईंको TV र व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको TV लाई हुनसक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुनुहुन्छ भन्ने कुरामा सहमत हुनुहुन्छ।"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"जारी राख्नुहोस्"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"सेटिङहरू"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"वेयर एपहरूको स्थापना/स्थापना रद्द गर्दै"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-nl-television/strings.xml b/packages/PackageInstaller/res/values-nl-television/strings.xml
new file mode 100644
index 0000000..c7256e8
--- /dev/null
+++ b/packages/PackageInstaller/res/values-nl-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Weigeren en niet meer vragen"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"U kunt dit later wijzigen in Instellingen > Apps"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Systeem weergeven"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"App-machtigingen"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"App-machtigingen"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Machtigingen voor <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Aanvullende machtigingen"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Machtigingen voor <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-nl-watch/strings.xml b/packages/PackageInstaller/res/values-nl-watch/strings.xml
new file mode 100644
index 0000000..338b79b
--- /dev/null
+++ b/packages/PackageInstaller/res/values-nl-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Weigeren, niet meer vragen"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Systeem weergeven"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Niet aanpasbaar"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ja"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Annuleren"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
new file mode 100644
index 0000000..a9e8940
--- /dev/null
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Pakket-installatie"</string>
+ <string name="next" msgid="3057143178373252333">"Volgende"</string>
+ <string name="install" msgid="5896438203900042068">"Installeren"</string>
+ <string name="done" msgid="3889387558374211719">"Gereed"</string>
+ <string name="cancel" msgid="8360346460165114585">"Annuleren"</string>
+ <string name="installing" msgid="8613631001631998372">"Installeren..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeren…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App geïnstalleerd."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Wil je deze app installeren? Deze krijgt toegang tot:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Wil je deze app installeren? Hiervoor is geen speciale toegang vereist."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Wil je een update voor deze bestaande app installeren? Je huidige gegevens gaan niet verloren. De bijgewerkte app krijgt toegang tot:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Wil je een update van deze ingebouwde app installeren? Je huidige gegevens gaan niet verloren. De bijgewerkte app krijgt toegang tot:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Wil je een update voor deze bestaande app installeren? Je huidige gegevens gaan niet verloren. Hiervoor is geen speciale toegang vereist."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Wil je een update voor deze ingebouwde app installeren? Je huidige gegevens gaan niet verloren. Hiervoor is geen speciale toegang vereist."</string>
+ <string name="install_failed" msgid="6579998651498970899">"App niet geïnstalleerd."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"De installatie van het pakket is geblokkeerd."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"App die niet is geïnstalleerd als pakket conflicteert met een bestaand pakket."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App die niet is geïnstalleerd als app is niet geschikt voor je tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Deze app is niet compatibel met je tv."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App die niet is geïnstalleerd als app is niet geschikt voor je telefoon."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"App die niet is geïnstalleerd als pakket lijkt ongeldig te zijn."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je tv."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je telefoon."</string>
+ <string name="launch" msgid="4826921505917605463">"Openen"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Je beheerder staat de installatie van apps afkomstig van onbekende bronnen niet toe"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Onbekende apps kunnen niet worden geïnstalleerd door deze gebruiker"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Deze gebruiker mag geen apps installeren"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Apps beheren"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Geen ruimte beschikbaar"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd. Maak ruimte vrij en probeer het opnieuw."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App niet gevonden"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"De app is niet gevonden in de lijst met geïnstalleerde apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Niet toegestaan"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"De huidige gebruiker mag deze verwijdering niet uitvoeren."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fout"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"App kan niet worden verwijderd."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"App verwijderen"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Update verwijderen"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> maakt deel uit van de volgende app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Wil je deze app verwijderen?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Wil je deze app verwijderen voor "<b>"alle"</b>" gebruikers? Deze app en de gegevens ervan worden verwijderd voor "<b>"alle"</b>" gebruikers van het apparaat."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Wil je deze app verwijderen voor de gebruiker <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd. Dit geldt voor alle gebruikers van het apparaat, dus ook voor gebruikers met een werkprofiel."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Actieve verwijderingen"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislukte verwijderingen"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Verwijderen..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderen…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Verwijdering voltooid."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderd"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Verwijdering mislukt."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kan niet worden verwijderd."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Kan actieve apparaatbeheer-app niet verwijderen"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kan actieve apparaatbeheer-app niet verwijderen voor <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Deze app is vereist voor sommige gebruikers of profielen en is verwijderd voor andere"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Deze app is vereist voor je profiel en kan niet worden verwijderd."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Deze app is vereist door je apparaatbeheerder en kan niet worden verwijderd."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Apparaatbeheer-apps beheren"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gebruikers beheren"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden verwijderd."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Er is een probleem opgetreden bij het parseren van het pakket."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nieuw"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Apparaattoegang"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Voor deze update zijn geen nieuwe machtigingen vereist."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Weigeren"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Meer informatie"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Toch weigeren"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> van <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> het volgende toestaan: <xliff:g id="ACTION">%2$s</xliff:g>."</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> altijd toestaan om <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Alleen als app in gebruik is"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Altijd"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Weigeren en niet meer vragen"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> uitgeschakeld"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"alle rechten uitgeschakeld"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"geen rechten uitgeschakeld"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Toestaan"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"App-machtigingen"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Niet meer vragen"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Geen machtigingen"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Aanvullende machtigingen"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"App-info openen"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Nog <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Nog <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Deze app is ontworpen voor een oudere versie van Android. Als u geen toestemming geeft, kan de app mogelijk niet functioneren zoals is bedoeld."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"een onbekende actie uitvoeren"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Verleend aan <xliff:g id="COUNT_0">%1$d</xliff:g> van <xliff:g id="COUNT_1">%2$d</xliff:g> apps"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Systeem weergeven"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Systeem-apps verbergen"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Geen apps"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Locatie-instellingen"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is een leverancier van locatieservices voor dit apparaat. Locatietoegang kan worden aangepast via de locatie-instellingen."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Als je deze machtiging weigert, kan het zijn dat basisfuncties van je apparaat niet meer werken zoals bedoeld."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Afgedwongen door beleid"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Toegang op de achtergrond uitgeschakeld op basis van beleid"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Toegang op de achtergrond ingeschakeld op basis van beleid"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Toegang op de voorgrond ingeschakeld op basis van beleid"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Ingesteld door beheerder"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Altijd"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Alleen als app in gebruik is"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nooit"</string>
+ <string name="loading" msgid="7811651799620593731">"Laden…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Alle machtigingen"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Andere app-mogelijkheden"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Toestemmingsverzoek"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Schermoverlay gedetecteerd"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Als u deze instelling voor rechten wilt wijzigen, moet u eerst de schermoverlay uitschakelen via \'Instellingen\' > \'Apps\'"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Instellingen openen"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Acties voor installeren/verwijderen niet ondersteund op Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Kiezen waartoe <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> toegang krijgt"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> is geüpdatet. Kies waartoe je deze app toegang wilt geven."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Annuleren"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Doorgaan"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nieuwe machtigingen"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Huidige machtigingen"</string>
+ <string name="message_staging" msgid="6151794817691100003">"App uitvoeren…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Onbekend"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Uit veiligheidsoverwegingen heeft je tablet geen toestemming om onbekende apps van deze bron te installeren."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Uit veiligheidsoverwegingen heeft je tv geen toestemming om onbekende apps van deze bron te installeren."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Uit veiligheidsoverwegingen heeft je telefoon geen toestemming om onbekende apps van deze bron te installeren."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Je telefoon en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je telefoon of gegevensverlies als gevolg van het gebruik van de app."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Je tablet en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tablet of gegevensverlies als gevolg van het gebruik van de app."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Je tv en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tv of gegevensverlies als gevolg van het gebruik van de app."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Doorgaan"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Instellingen"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear-apps installeren/verwijderen"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-notround-watch/dimens.xml b/packages/PackageInstaller/res/values-notround-watch/dimens.xml
new file mode 100644
index 0000000..55d6248
--- /dev/null
+++ b/packages/PackageInstaller/res/values-notround-watch/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Dimens for dialog layouts -->
+ <dimen name="diag_button_size">44dp</dimen>
+ <dimen name="diag_preferred_padding">8dp</dimen>
+ <dimen name="diag_button_padding_horizontal">16dp</dimen>
+ <dimen name="diag_button_padding_bottom">8dp</dimen>
+ <dimen name="diag_icon_margin_top">8dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-or-television/strings.xml b/packages/PackageInstaller/res/values-or-television/strings.xml
new file mode 100644
index 0000000..157b922
--- /dev/null
+++ b/packages/PackageInstaller/res/values-or-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"ମନାକରନ୍ତୁ ଏବଂ ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ସେଟିଙ୍ଗ ଓ ଆପ୍ରେ ଏହାକୁ ଆପଣ ପରେ ବଦଳାଇପାରିବେ"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"ସିଷ୍ଟମ୍ ଆପ୍ ଦେଖାନ୍ତୁ"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ଆପ୍ର ଅନୁମତି"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ଆପ୍ର ଅନୁମତି"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> ଅନୁମତି"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"ଅତିରିକ୍ତ ଅନୁମତି"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> ଅନୁମତି"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-or-watch/strings.xml b/packages/PackageInstaller/res/values-or-watch/strings.xml
new file mode 100644
index 0000000..b7719a1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-or-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ମନାକରନ୍ତୁ, ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"ସିଷ୍ଟମ୍ ଆପ୍ ଦେଖାନ୍ତୁ"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ବଦଳାଯାଇପାରିବ ନାହିଁ"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ହଁ"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"କ୍ୟାନ୍ସଲ୍ କରନ୍ତୁ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
new file mode 100644
index 0000000..8d93c6f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-or/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"ପ୍ୟାକେଜ୍ ଇନଷ୍ଟଲର୍"</string>
+ <string name="next" msgid="3057143178373252333">"ପରବର୍ତ୍ତୀ"</string>
+ <string name="install" msgid="5896438203900042068">"ଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
+ <string name="done" msgid="3889387558374211719">"ହୋଇଗଲା"</string>
+ <string name="cancel" msgid="8360346460165114585">"କ୍ୟାନ୍ସଲ୍ କରନ୍ତୁ"</string>
+ <string name="installing" msgid="8613631001631998372">"ଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇଗଲା।"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ଏହି ଆପ୍ଲିକେଶନ୍ ଆପଣ ଇନଷ୍ଟଲ୍ କରିବେ କି? ଏହିଗୁଡ଼ିକୁ ଏହା ଆକ୍ସେସ୍ କରିପାରିବ:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ଏହି ଆପ୍ଲିକେଶନ୍ ଆପଣ ଇନଷ୍ଟଲ୍ କରିବେ କି? ଏହା କୌଣସି ବିଶେଷ ପ୍ରକାରର ଆକ୍ସେସ୍ ଆବଶ୍ୟକ କରେନାହିଁ।"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"ପୂର୍ବରୁ ଥିବା ଏହି ଆପ୍ଲିକେଶନ୍ରେ ଆପଣ ଏକ ଅପଡେଟ୍ ଇନଷ୍ଟଲ୍ କରିବେ କି? ଏଥିରେ ଥିବା ଆପଣଙ୍କ ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଅପଡେଟ୍ ହେବାପରେ ଆପ୍ଲିକେଶନ୍ଟି ଏହିଗୁଡ଼ିକୁ ଆକ୍ସେସ୍ କରିପାରିବ:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ଏହି ବିଲ୍ଟ-ଇନ୍ ଆପ୍ଲିକେଶନ୍ରେ ଆପଣ ଏକ ଅପଡେଟ୍ ଇନଷ୍ଟଲ୍ କରିବେ କି? ଏଥିରେ ଥିବା ଆପଣଙ୍କ ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଅପଡେଟ୍ ହେବାପରେ ଆପ୍ଲିକେଶନ୍ଟି ଏହିଗୁଡ଼ିକୁ ଆକ୍ସେସ୍ କରିପାରିବ:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ଆପଣ ବର୍ତ୍ତମାନର ଏହି ଆପ୍ଲିକେଶନ୍ର ଏକ ଅପଡେଟ୍ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଚାହୁଁଛନ୍ତି କି? ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଏଥିରେ କୌଣସି ବିଶେଷ ଆକ୍ସେସ୍ର ଆବଶ୍ୟକତା ନାହିଁ।"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ଆପଣ ବର୍ତ୍ତମାନର ଏହି ବିଲ୍ଟ-ଇନ୍ ଆପ୍ଲିକେଶନ୍ର ଏକ ଅପଡେଟ୍ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଚାହୁଁଛନ୍ତି କି? ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଏଥିରେ କୌଣସି ବିଶେଷ ଆକ୍ସେସ୍ର ଆବଶ୍ୟକତା ନାହିଁ।"</string>
+ <string name="install_failed" msgid="6579998651498970899">"ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇନାହିଁ।"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ଏହି ପ୍ୟାକେଜ୍କୁ ଇନଷ୍ଟଲ୍ କରାଯିବାରେ ଅବରୋଧ କରାଯାଇଥିଲା।"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ପୂର୍ବରୁ ଥିବା ପ୍ୟାକେଜ୍ ସହ ଏହି ପ୍ୟାକେଜ୍ର ସମସ୍ୟା ଉପୁଯିବାରୁ ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇପାରିଲା ନାହିଁ।"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ଆପ୍ ଆପଣଙ୍କ ଟାବଲେଟ୍ ସହ କମ୍ପାଟିବଲ୍ ନଥିବା ହେତୁ ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇପାରିଲା ନାହିଁ।"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ଏହି ଆପ୍, ଆପଣଙ୍କ ଟିଭି ସହ କମ୍ପାଟିବଲ୍ ନୁହେଁ।"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ଆପ୍ ଆପଣଙ୍କ ଫୋନ୍ ସହ କମ୍ପାଟିବଲ୍ ନଥିବା ହେତୁ ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇପାରିଲା ନାହିଁ।"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ପ୍ୟାକେଜ୍ ଅମାନ୍ୟ ଥିବା ପରି ଜଣାପଡ଼ିବାରୁ ଆପ୍ ଇନଷ୍ଟଲ୍ ହୋଇପାରିଲା ନାହିଁ।"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>ଟି ଆପଣଙ୍କ ଟାବଲେଟ୍ରେ ଇନଷ୍ଟଲ୍ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ ଟିଭିରେ ଇନଷ୍ଟଲ୍ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ଟି ଆପଣଙ୍କ ଫୋନ୍ରେ ଇନଷ୍ଟଲ୍ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+ <string name="launch" msgid="4826921505917605463">"ଖୋଲନ୍ତୁ"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ଅଜଣା ସୋର୍ସରୁ ଆସିଥିବା ଆପଗୁଡ଼ିକ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଆପଣଙ୍କ ଆଡମିନ୍ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ଏହି ୟୁଜରଙ୍କ ଦ୍ୱାରା ଅଜଣା ଆପ୍ ଇନଷ୍ଟଲ୍ କରାଯାଇ ପାରିବ ନାହିଁ"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ଏହି ୟୁଜର୍ ଜଣକ ଆପ୍ ଇନଷ୍ଟଲ୍ କରିପାରିବେ ନାହିଁ"</string>
+ <string name="ok" msgid="3468756155452870475">"ଠିକ୍ ଅଛି"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"ଆପ୍ଗୁଡ଼ିକର ପରିଚାଳନା କରନ୍ତୁ"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ଆଉ ସ୍ଥାନ ନାହିଁ"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଇନଷ୍ଟଲ୍ କରାଯାଇପାରିଲା ନାହିଁ। କିଛି ସ୍ଥାନ ଖାଲିକରି ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ଆପ୍ ମିଳିଲା ନାହିଁ"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ଇନଷ୍ଟଲ୍ କରାଯାଇଥିବା ଆପ୍ ତାଲିକାରେ ଆପ୍ଟି ମିଳିଲା ନାହିଁ।"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ଅନୁମତି ଦିଆଯାଇନାହିଁ"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ଏହି ଅନଇନଷ୍ଟଲେଶନ୍ କରିବାକୁ ବର୍ତ୍ତମାନର ୟୁଜରଙ୍କୁ ଅନୁମତି ଦିଆଯାଇନାହିଁ।"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ତ୍ରୁଟି"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ଆପ୍ ଅନଇନଷ୍ଟଲ୍ କରାହେଲା ନାହିଁ"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ଆପ୍ ଅନଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"ଅପଡେଟ୍ ଅନଇନଷ୍ଟଲ୍ କରନ୍ତୁ"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ହେଉଛି ନିମ୍ନ ଆପ୍ର ଏକ ଅଂଶ।"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ଆପଣ ଏହି ଆପ୍ ଅନଇନଷ୍ଟଲ୍ କରିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ଆପଣ "<b>"ସମସ୍ତ"</b>" ୟୁଜର୍ଙ୍କ ପାଇଁ ଏହି ଆପ୍କୁ ଅନଷ୍ଟଲ୍ କରିବାକୁ ଚାହୁଁଛନ୍ତି କି? ଡିଭାଇସ୍ରେ ଥିବା "<b>"ସମସ୍ତ"</b>" ୟୁଜର୍ ଆପ୍ଲିକେଶନ୍ ଏବଂ ତାହାର ଡାଟା ବାହାର କରିଦିଆଯିବ।"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"ୟୁଜର୍ <xliff:g id="USERNAME">%1$s</xliff:g>ଙ୍କ ପାଇଁ ଆପଣ ଏହି ଆପ୍ ଇନଷ୍ଟଲ୍ କରିବେ କି?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ଏହି ଆପ୍ ଫ୍ୟାକ୍ଟୋରୀ ଭର୍ସନ୍ ସହ ବଦଳାଇବେ? ସମସ୍ତ ଡାଟା କାଢ଼ିଦିଆଯିବ।"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ଏହି ଆପ୍ ଫ୍ୟାକ୍ଟୋରୀ ଭର୍ସନ୍ ସହ ବଦଳାଇବେ? ସମସ୍ତ ଡାଟା ବାହାର କରିଦିଆଯିବ। ୱର୍କ ପ୍ରୋଫାଇଲ୍ ଥିବା ସମେତ, ଏହାଦ୍ୱାରା ଡିଭାଇସରେ ଥିବା ସମସ୍ତ ୟୁଜର୍ ପ୍ରଭାବିତ ହେବେ।"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ଅନଇନଷ୍ଟଲ୍ ଚାଲୁଛି"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ଅନଇନଷ୍ଟଲ୍ କରାଯାଇ ପାରିଲା ନାହିଁ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"ଅନଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"ଅନଇନଷ୍ଟଲ୍ ହୋଇଗଲା।"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍ କରାଗଲା"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ଅନଇନଷ୍ଟଲ୍ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍ କରିବା ସଫଳ ହେଲାନାହିଁ।"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ସକ୍ରିୟ ଡିଭାଇସ୍ ଆପ୍ ଅନଇନଷ୍ଟଲ୍ କରିପାରିବ ନାହିଁ"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>ଙ୍କ ପାଇଁ ସକ୍ରିୟ ଡିଭାଇସ୍ ଆଡମିନ୍ ଆପ୍ ଅନଇନଷ୍ଟଲ୍ କରାଯାଇ ପାରିବ ନାହିଁ"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"କିଛି ୟୁଜର୍ କିମ୍ବା ପ୍ରୋଫାଇଲ୍ ପାଇଁ ଏହି ଆପ୍ ଆବଶ୍ୟକ ଏବଂ ଅନ୍ୟ ସମସ୍ତଙ୍କ ପାଇଁ ଅନଇନଷ୍ଟଲ୍ କରାଯାଇଥିଲା"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ଏହି ଆପ୍ ଆପଣଙ୍କ ପ୍ରୋଫାଇଲ୍ ପାଇଁ ଆବଶ୍ୟକ ଅଟେ ଏବଂ ଅନଇନଷ୍ଟଲ୍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ଆପଣଙ୍କ ଡିଭାଇସ୍ ଆଡମିନିଷ୍ଟ୍ରେଟର୍ ଏହି ଆପ୍ ଆବଶ୍ୟକ କରନ୍ତୁ ଏବଂ ଏହାକୁ ଅନ୍ଇନଷ୍ଟଲ୍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ଡିଭାଇସ୍ ଆଡମିନ୍ ଆପ୍ ପରିଚାଳନା କରନ୍ତୁ"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ୟୁଜର୍ଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ଏହି ପ୍ୟାକେଜ୍ ପାର୍ସ କରିବାରେ ସମସ୍ୟା ଥିଲା।"</string>
+ <string name="newPerms" msgid="6039428254474104210">"ନୂଆ"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ସମସ୍ତ"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ଗୋପନୀୟତା"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ଡିଭାଇସ୍ ଆକ୍ସେସ୍"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ଏହି ଅପଡେଟ୍ କୌଣସି ନୂଆ ଅନୁମତି ଆବଶ୍ୟକ କରେନାହିଁ"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ପ୍ରତ୍ୟାଖ୍ୟାନ"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ଅଧିକ ସୂଚନା"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ତଥାପି ଖାରଜ କରନ୍ତୁ"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>ଟିରୁ <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>ଟି"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>କୁ <xliff:g id="ACTION">%2$s</xliff:g> ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ସବୁବେଳେ <xliff:g id="ACTION">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"କେବଳ ଆପ୍ ବ୍ୟବହାର କରୁଥିବା ସମୟରେ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ସର୍ବଦା"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ମନାକରନ୍ତୁ ଏବଂ ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>ଟି ଅକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"ସମସ୍ତ ଅକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"କିଛିବି ଅକ୍ଷମ କରାଯାଇନାହିଁ"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ଆପ୍"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ଆପ୍ ଅନୁମତି"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"କୌଣସି ଅନୁମତି ନାହିଁ"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"ଅତିରିକ୍ତ ଅନୁମତି"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ଆପ୍ର ତଥ୍ୟ ଖୋଲନ୍ତୁ"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଅଧିକ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଅଧିକ</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ଏହି ଆପ୍ Androidର ଏକ ପୁରୁଣା ସଂସ୍କରଣ ପାଇଁ ଡିଜାଇନ୍ କରାଯାଇଥିଲା। ଅନୁମତି ପ୍ରତ୍ୟାଖ୍ୟାନ କରିବା ଦ୍ୱାରା ଏହା ଠିକ୍ ଭାବେ ଆଉ କାମ ନକରିପାରେ।"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ଏକ ଅଜଣା କାମ କରେ"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>ଟି ଆପରୁ <xliff:g id="COUNT_0">%1$d</xliff:g>ଟିକୁ ଅନୁମତି ଦିଆଯାଇଛି"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"ସିଷ୍ଟମ୍କୁ ଦେଖାନ୍ତୁ"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"ସିଷ୍ଟମ୍କୁ ଲୁଚାନ୍ତୁ"</string>
+ <string name="no_apps" msgid="1965493419005012569">"କୌଣସି ଆପ୍ ନାହିଁ"</string>
+ <string name="location_settings" msgid="1774875730854491297">"ଲୋକେଶନ୍ ସେଟିଙ୍ଗ"</string>
+ <string name="location_warning" msgid="8778701356292735971">"ଏହି ଡିଭାଇସ୍ ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଲୋକେଶନ୍ ସେବା ପ୍ରଦାନ କରେ। ଲୋକେଶନ୍ ସେଟିଙ୍ଗରୁ ଲୋକେଶନ୍ ଆକ୍ସେସ୍ ସଂଶୋଧନ କରାଯାଇପାରିବ।"</string>
+ <string name="system_warning" msgid="7103819124542305179">"ଏହି ଅନୁମତିକୁ ଯଦି ଆପଣ ପ୍ରତ୍ୟାଖ୍ୟାନ କରନ୍ତି, ଆପଣଙ୍କ ଡିଭାଇସ୍ର ସାଧାରଣ ସୁବିଧାଗୁଡ଼ିକ ଆଉ କାମ ନକରିପାରେ।"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ପଲିସୀ ଦ୍ୱାରା ଲାଗୁ"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ନିତୀ ଅନୁସାରେ ବ୍ୟାକ୍ଗ୍ରାଉଣ୍ଡ ଆକ୍ସେସ୍ ଅକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ନିତୀ ଅନୁସାରେ ପୃଷ୍ଠପଟ ଆକ୍ସେସ୍ ସକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ନିତୀ ଅନୁସାରେ ସମ୍ମୁଖଭାଗ ଆକ୍ସେସ୍ ସକ୍ଷମ କରାଯାଇଛି"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ଆଡ୍ମିନ୍ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ସର୍ବଦା"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"କେବଳ ଆପ୍ ବ୍ୟବହାର କରୁଥିବା ସମୟରେ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"କେବେ ନୁହେଁ"</string>
+ <string name="loading" msgid="7811651799620593731">"ଲୋଡ୍ କରାଯାଉଛି…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"ସମସ୍ତ ଅନୁମତି"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"ଅନ୍ୟାନ୍ୟ ଆପ୍ ଦକ୍ଷତା"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"ଅନୁମତି ଅନୁରୋଧ"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"ସ୍କ୍ରୀନ୍ ଓଭର୍ଲେ ଚିହ୍ନଟ ହୋଇଛି"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ଏହି ଅନୁମତି ସେଟିଙ୍ଗ ବଦଳାଇବାକୁ, ପ୍ରଥମେ ଆପଣ ସେଟିଙ୍ଗ ଓ ଆପ୍ରୁ ସ୍କ୍ରୀନ୍ ଅଫ୍ କରନ୍ତୁ"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android ୱିୟର୍"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wearରେ ଇନଷ୍ଟଲ୍/ଅନଇନଷ୍ଟଲ୍ କାର୍ଯ୍ୟ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ଆକ୍ସେସ୍ କରିବା ପାଇଁ କ\'ଣ କ\'ଣ ଅନୁମତି ଦିଆଯିବ, ତାହା ବାଛନ୍ତୁ"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ଅପଡେଟ୍ କରାଯାଇଛି। ଏହି ଆପ୍ କ\'ଣ କ\'ଣ ଆକ୍ସେସ୍ କରିପାରିବ, ତାହା ବାଛନ୍ତୁ।"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"କ୍ୟାନ୍ସଲ୍ କରନ୍ତୁ"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ଜାରି ରଖନ୍ତୁ"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"ନୂଆ ଅନୁମତି"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"ବର୍ତ୍ତମାନର ଅନୁମତି"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ଆପ୍ ପର୍ଯ୍ୟାୟଭୁକ୍ତ କରାଯାଉଛି…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"ଅଜଣା"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ଆପଣଙ୍କ ସୁରକ୍ଷା ପାଇଁ, ଆପଣଙ୍କ ଟାବଲେଟକୁ ଏହି ସୋର୍ସରୁ ଆସିଥିବା ଅଜଣା ଆପ୍ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ।"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ଆପଣଙ୍କ ସୁରକ୍ଷା ପାଇଁ, ଆପଣଙ୍କ ଟିଭିକୁ ଏହି ସୋର୍ସରୁ ଆସିଥିବା ଅଜଣା ଆପ୍ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ।"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ଆପଣଙ୍କ ସୁରକ୍ଷା ପାଇଁ, ଆପଣଙ୍କ ଫୋନକୁ ଏହି ସୋର୍ସରୁ ଆସିଥିବା ଅଜଣା ଆପ୍ ଇନଷ୍ଟଲ୍ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ।"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ଅଜଣା ଆପ୍ ଦ୍ୱାରା ଆପଣଙ୍କ ଫୋନ୍ ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇ ପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପଜୁ ଇନଷ୍ଟଲ୍ କରିବାର ଅର୍ଥ, ଆପଣଙ୍କ ଫୋନରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ଅଜଣା ଆପ୍ ଦ୍ୱାରା ଆପଣଙ୍କ ଟାବଲେଟ୍ ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇ ପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପଜୁ ଇନଷ୍ଟଲ୍ କରିବାର ଅର୍ଥ, ଆପଣଙ୍କ ଟାବଲେଟରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ଅଜଣା ଆପ୍ ଦ୍ୱାରା ଆପଣଙ୍କ ଟିଭି ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇ ପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପଜୁ ଇନଷ୍ଟଲ୍ କରିବାର ଅର୍ଥ, ଆପଣଙ୍କ ଟିଭିରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ଜାରି ରଖନ୍ତୁ"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ସେଟିଙ୍ଗ"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"ୱେର୍ ଆପ୍ ଇନଷ୍ଟଲ୍/ଅନଇନଷ୍ଟଲ୍ କରାଯାଉଛି"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pa-television/strings.xml b/packages/PackageInstaller/res/values-pa-television/strings.xml
new file mode 100644
index 0000000..76d249c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pa-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"ਅਸਵੀਕਾਰ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ ਸੈਟਿੰਗਾਂ > ਐਪਾਂ ਵਿੱਚ ਬਦਲ ਸਕਦੇ ਹੋ"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"ਸਿਸਟਮ ਐਪਸ ਦਿਖਾਓ"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ਐਪ ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ਐਪ ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"ਵਧੀਕ ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> ਇਜਾਜ਼ਤਾਂ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pa-watch/strings.xml b/packages/PackageInstaller/res/values-pa-watch/strings.xml
new file mode 100644
index 0000000..e093021
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pa-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ਅਸਵੀਕਾਰ ਕਰੋ, ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"ਸਿਸਟਮ ਐਪਸ ਦਿਖਾਓ"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ਬਦਲਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ਹਾਂ"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"ਰੱਦ ਕਰੋ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
new file mode 100644
index 0000000..b364c78
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"ਪੈਕੇਜ ਸਥਾਪਨਾਕਾਰ"</string>
+ <string name="next" msgid="3057143178373252333">"ਅੱਗੇ"</string>
+ <string name="install" msgid="5896438203900042068">"ਸਥਾਪਤ ਕਰੋ"</string>
+ <string name="done" msgid="3889387558374211719">"ਹੋ ਗਿਆ"</string>
+ <string name="cancel" msgid="8360346460165114585">"ਰੱਦ ਕਰੋ"</string>
+ <string name="installing" msgid="8613631001631998372">"ਇੰਸਟੌਲ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ਐਪ ਇੰਸਟੌਲ ਕੀਤਾ।"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ਕੀ ਤੁਸੀਂ ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਇਹ ਇਸ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੇਗਾ:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਇਸ ਲਈ ਕਿਸੇ ਖਾਸ ਪਹੁੰਚ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"ਕੀ ਤੁਸੀਂ ਇਸ ਮੌਜੂਦਾ ਐਪਲੀਕੇਸ਼ਨ ਤੇ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਕੀਤਾ ਜਾਏਗਾ। ਅੱਪਡੇਟ ਕੀਤੀ ਐਪਲੀਕੇਸ਼ਨ ਇਸ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੇਗੀ:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ਕੀ ਤੁਸੀਂ ਇਸ ਬਿਲਟ-ਇਨ ਐਪਲੀਕੇਸ਼ਨ ਤੇ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਕੀਤਾ ਜਾਏਗਾ। ਅੱਪਡੇਟ ਕੀਤੀ ਐਪਲੀਕੇਸ਼ਨ ਇਸ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੇਗੀ:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ਕੀ ਤੁਸੀਂ ਇਸ ਮੌਜੂਦਾ ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਨਹੀਂ ਹੋਵੇਗਾ। ਇਸ ਲਈ ਕਿਸੇ ਖਾਸ ਪਹੁੰਚ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ਕੀ ਤੁਸੀਂ ਇਸ ਬਿਲਟ-ਇਨ ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਨਹੀਂ ਹੋਵੇਗਾ। ਇਸ ਲਈ ਕਿਸੇ ਖਾਸ ਪਹੁੰਚ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
+ <string name="install_failed" msgid="6579998651498970899">"ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ।"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ਪੈਕੇਜ ਨੂੰ ਸਥਾਪਿਤ ਹੋਣ ਤੋਂ ਬਲੌਕ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ਪੈਕੇਜ ਦੇ ਇੱਕ ਮੌਜੂਦਾ ਪੈਕੇਜ ਨਾਲ ਵਿਵਾਦ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ਐਪ ਦੇ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਦੇ ਅਨੁਰੂਪ ਨਾ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ ਦੇ ਅਨੁਕੂਲ ਨਹੀਂ ਹੈ।"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ਐਪ ਦੇ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੇ ਅਨੁਰੂਪ ਨਾ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ਪੈਕੇਜ ਦੇ ਅਵੈਧ ਪ੍ਰਤੀਤ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੈੱਟ ਤੇ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ TV ਤੇ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੇ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
+ <string name="launch" msgid="4826921505917605463">"ਖੋਲ੍ਹੋ"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਅਗਿਆਤ ਸਰੋਤਾਂ ਤੋਂ ਪ੍ਰਾਪਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦਾ"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ਇਸ ਵਰਤੋਂਕਾਰ ਵੱਲੋਂ ਅਗਿਆਤ ਐਪਾਂ ਨੂੰ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
+ <string name="ok" msgid="3468756155452870475">"ਠੀਕ"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"ਐਪਸ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ਖਾਲੀ ਸਪੇਸ"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕੁਝ ਸਪੇਸ ਖਾਲੀ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ਐਪ ਨਹੀਂ ਮਿਲਿਆ"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ਐਪ ਇੰਸਟੌਲ ਕੀਤੇ ਐਪਸ ਦੀ ਸੂਚੀ ਵਿੱਚ ਨਹੀਂ ਮਿਲਿਆ ਸੀ।"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ਇਜਾਜ਼ਤ ਨਹੀਂ"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ਮੌਜੂਦਾ ਵਰਤੋਂਕਾਰ ਨੂੰ ਇਹ ਅਣਸਥਾਪਨਾ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ।"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ਗੜਬੜ"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ਐਪ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ।"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ਐਪ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"ਅੱਪਡੇਟ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ਇਸ ਐਪ ਦਾ ਭਾਗ ਹੈ:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ "<b>"ਸਾਰੇ"</b>" ਵਰਤੋਂਕਾਰਾਂ ਲਈ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਐਪਲੀਕੇਸ਼ਨ ਅਤੇ ਇਸਦਾ ਡਾਟਾ ਡੀਵਾਈਸ ਤੇ "<b>"ਸਾਰੇ"</b>" ਵਰਤੋਂਕਾਰਾਂ ਵੱਲੋਂ ਹਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"ਕੀ ਤੁਸੀਂ ਵਰਤੋਂਕਾਰ <xliff:g id="USERNAME">%1$s</xliff:g> ਲਈ ਇਸ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ਕੀ ਇਸ ਐਪ ਨੂੰ ਫੈਕਟਰੀ ਸੰਸਕਰਣ ਨਾਲ ਬਦਲਣਾ ਹੈ? ਸਾਰਾ ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ਕੀ ਇਸ ਐਪ ਨੂੰ ਫੈਕਟਰੀ ਵਰਜਨ ਨਾਲ ਬਦਲਣਾ ਹੈ? ਸਾਰਾ ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ। ਇਹ ਇਸ ਡੀਵਾਈਸ ਦੇ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰੇਗਾ, ਜਿਸ ਵਿੱਚ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਾਲੇ ਵਰਤੋਂਕਾਰ ਵੀ ਸ਼ਾਮਲ ਹਨ।"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ਚੱਲ ਰਹੀਆਂ ਅਣਸਥਾਪਨਾਵਾਂ"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ਅਸਫਲ ਅਣਸਥਾਪਨਾਵਾਂ"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"ਅਣਇੰਸਟੌਲ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"ਅਣਸਥਾਪਨਾ ਪੂਰੀ ਹੋਈ।"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ਅਣਸਥਾਪਨਾ ਅਸਫਲ।"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ।"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ਕਿਰਿਆਸ਼ੀਲ ਡੀਵਾਈਸ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> ਲਈ ਕਿਰਿਆਸ਼ੀਲ ਡੀਵਾਈਸ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ਇਹ ਐਪ ਕੁਝ ਵਰਤੋਂਕਾਰਾਂ ਜਾਂ ਪ੍ਰੋਫਾਈਲਾਂ ਲਈ ਲੋੜੀਂਦੀ ਹੈ ਅਤੇ ਹੋਰਾਂ ਲਈ ਅਣਸਥਾਪਤ ਕੀਤੀ ਗਈ ਸੀ"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ਇਹ ਐਪ ਤੁਹਾਡੀ ਪ੍ਰੋਫਾਈਲ ਲਈ ਲੋੜੀਂਦੀ ਹੈ ਅਤੇ ਇਸ ਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਕ ਵੱਲੋਂ ਲੋੜੀਂਦੀ ਹੈ ਅਤੇ ਇਸਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"ਡੀਵਾਈਸ ਪ੍ਰਸ਼ਾਸਕ ਐਪਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
+ <string name="manage_users" msgid="3125018886835668847">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਅਣਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ਪੈਕੇਜ ਨੂੰ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਇੱਕ ਸਮੱਸਿਆ ਸੀ।"</string>
+ <string name="newPerms" msgid="6039428254474104210">"ਨਵਾਂ"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ਸਭ"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ਪ੍ਰਾਈਵੇਸੀ"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"ਡੀਵਾਈਸ ਪਹੁੰਚ"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ਇਸ ਅੱਪਡੇਟ ਲਈ ਕਿਸੇ ਨਵੀਆਂ ਅਨੁਮਤੀਆਂ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ਹੋਰ ਜਾਣਕਾਰੀ"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ਫੇਰ ਵੀ ਅਸਵੀਕਾਰ ਕਰੋ"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> ਦਾ <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"ਕੀ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ <xliff:g id="ACTION">%2$s</xliff:g> ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"ਹਮੇਸ਼ਾਂ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ <xliff:g id="ACTION">%2$s</xliff:g> ਕਰਨ ਦਿਓ?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ਸਿਰਫ਼ ਐਪ ਵਰਤਣ ਵੇਲੇ"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ਹਮੇਸ਼ਾਂ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ਅਸਵੀਕਾਰ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"ਸਭ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ਕਿਸੇ ਨੂੰ ਵੀ ਅਯੋਗ ਨਹੀਂ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ਆਗਿਆ ਦਿਓ"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ਐਪਾਂ"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ਐਪ ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ਕੋਈ ਇਜਾਜ਼ਤਾਂ ਨਹੀਂ ਹਨ"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"ਵਧੀਕ ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ਐਪ ਜਾਣਕਾਰੀ ਖੋਲ੍ਹੋ"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਹੋਰ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਹੋਰ</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ਇਹ ਐਪ Android ਦੇ ਕਿਸੇ ਪੁਰਾਣੇ ਸੰਸਕਰਣ ਲਈ ਬਣਾਈ ਗਈ ਸੀ। ਅਨੁਮਤੀ ਨੂੰ ਇਨਕਾਰ ਕਰਨਾ ਇਸਦੇ ਉਦੇਸ਼ਿਤ ਫੰਕਸ਼ਨ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ਕੋਈ ਅਗਿਆਤ ਕਾਰਵਾਈ ਕਰੋ"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> ਵਿੱਚੋਂ <xliff:g id="COUNT_0">%1$d</xliff:g> ਐਪਾਂ ਨੂੰ ਆਗਿਆ ਦਿੱਤੀ"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"ਸਿਸਟਮ ਦਿਖਾਓ"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"ਸਿਸਟਮ ਲੁਕਾਓ"</string>
+ <string name="no_apps" msgid="1965493419005012569">"ਕੋਈ ਐਪਾਂ ਨਹੀਂ"</string>
+ <string name="location_settings" msgid="1774875730854491297">"ਟਿਕਾਣਾ ਸੈਟਿੰਗਾਂ"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਇਸ ਡੀਵਾਈਸ ਲਈ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦਾ ਇੱਕ ਪ੍ਰਦਾਤਾ ਹੈ। ਟਿਕਾਣਾ ਪਹੁੰਚ ਨੂੰ ਟਿਕਾਣਾ ਸੈਟਿੰਗਾਂ ਤੋਂ ਸੰਸ਼ੋਧਿਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।"</string>
+ <string name="system_warning" msgid="7103819124542305179">"ਜੇਕਰ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀਆਂ ਮੂੂਲ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਆਪਣੇ ਫੰਕਸ਼ਨ ਮੁਤਾਬਕ ਕੰਮ ਨਹੀਂ ਵੀ ਕਰ ਸਕਦੀਆਂ।"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ਨੀਤੀ ਮੁਤਾਬਕ ਲਾਗੂ ਕੀਤਾ"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ਨੀਤੀ ਵੱਲੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ਨੀਤੀ ਵੱਲੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ਨੀਤੀ ਵੱਲੋਂ ਫੋਰਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ਹਮੇਸ਼ਾਂ"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ਸਿਰਫ਼ ਐਪ ਵਰਤਣ ਦੌਰਾਨ"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ਕਦੇ ਵੀ ਨਹੀਂ"</string>
+ <string name="loading" msgid="7811651799620593731">"ਲੋਡ ਕਰ ਰਿਹਾ ਹੈ…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"ਸਾਰੀਆਂ ਅਨੁਮਤੀਆਂ"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"ਹੋਰ ਐਪ ਸਮਰੱਥਤਾਵਾਂ"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"ਇਜਾਜ਼ਤ ਬੇਨਤੀ"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"ਸਕਰੀਨ ਓਵਰਲੇਅ ਲੱਭ ਗਿਆ"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ਇਸ ਇਜ਼ਾਜਤ ਸੈਟਿੰਗ ਨੂੰ ਬਦਲਣ ਲਈ; ਤੁਹਾਨੂੰ ਪਹਿਲਾਂ ਸੈਟਿੰਗਾਂ ਅਤੇ ਐਪਾਂ ਤੋਂ ਸਕ੍ਰੀਨ ਓਵਰਲੇਅ ਬੰਦ ਕਰਨਾ ਪਵੇਗਾ"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ਵੀਅਰ \'ਤੇ ਸਥਾਪਤ/ਅਣਸਥਾਪਤ ਕਾਰਵਾਈਆਂ ਸਮਰਥਿਤ ਨਹੀਂ ਹਨ।"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"ਇਹ ਚੁਣੋ ਕਿ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਕਿਸ \'ਤੇ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ਨੂੰ ਅੱਪਡੇਟ ਕੀਤਾ ਜਾ ਚੁੱਕਿਆ ਹੈ। ਇਹ ਚੁਣੋ ਕਿ ਇਸ ਐਪ ਨੂੰ ਕਿਸ \'ਤੇ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ।"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"ਰੱਦ ਕਰੋ"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ਜਾਰੀ ਰੱਖੋ"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"ਨਵੀਆਂ ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"ਵਰਤਮਾਨ ਇਜਾਜ਼ਤਾਂ"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ਐਪ ਨੂੰ ਪੜਾਅਬੱਧ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"ਅਗਿਆਤ"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਟੀਵੀ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਫ਼ੋਨ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ਿੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਕਮਜ਼ੋਰ ਹੈ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ਿੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ਤੁਹਾਡਾ ਟੀਵੀ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੀਵੀ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ਿੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ਜਾਰੀ ਰੱਖੋ"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ਸੈਟਿੰਗਾਂ"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"ਵੀਅਰ ਐਪਾਂ ਨੂੰ ਸਥਾਪਤ/ਅਣਸਥਾਪਤ ਕਰਨਾ"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pl-television/strings.xml b/packages/PackageInstaller/res/values-pl-television/strings.xml
new file mode 100644
index 0000000..6fede9a
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pl-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Odmów i nie pytaj ponownie"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Możesz to później zmienić, wybierając Ustawienia > Aplikacje"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Pokaż aplikacje systemowe"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Uprawnienia aplikacji"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Uprawnienia aplikacji"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> – uprawnienia"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Dodatkowe uprawnienia"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> – uprawnienia"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pl-watch/strings.xml b/packages/PackageInstaller/res/values-pl-watch/strings.xml
new file mode 100644
index 0000000..95c3687
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pl-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Odmów i nie pytaj ponownie"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Pokaż aplikacje systemowe"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Nie można zmienić"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Tak"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Anuluj"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
new file mode 100644
index 0000000..dbedfad
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Instalator pakietu"</string>
+ <string name="next" msgid="3057143178373252333">"Dalej"</string>
+ <string name="install" msgid="5896438203900042068">"Instaluj"</string>
+ <string name="done" msgid="3889387558374211719">"Gotowe"</string>
+ <string name="cancel" msgid="8360346460165114585">"Anuluj"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalowanie..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instaluję pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikacja została zainstalowana."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Zainstalować tę aplikację? Będzie miała następujące uprawnienia:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Zainstalować tę aplikację? Nie ma specjalnych wymagań dotyczących dostępu."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Zainstalować aktualizację tej aplikacji? Nie utracisz wcześniejszych danych. Zaktualizowana aplikacja będzie miała następujące uprawnienia:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Zainstalować aktualizację fabrycznej aplikacji? Nie utracisz wcześniejszych danych. Zaktualizowana aplikacja będzie miała następujące uprawnienia:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Chcesz zaktualizować tę istniejącą aplikację? Nie utracisz danych. Nie są wymagane specjalne uprawnienia dostępu."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Chcesz zaktualizować tę wbudowaną aplikację? Nie utracisz danych. Nie są wymagane specjalne uprawnienia dostępu."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikacja nie została zainstalowana."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Instalacja pakietu została zablokowana."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacja nie została zainstalowana, bo powoduje konflikt z istniejącym pakietem."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacja nie została zainstalowana, bo jest niezgodna z Twoim tabletem."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikacja jest niezgodna z Twoim telewizorem."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacja nie została zainstalowana, bo jest niezgodna z Twoim telefonem."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacja nie została zainstalowana, bo pakiet wygląda na nieprawidłowy."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim tablecie."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nie udało się zainstalować <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim telewizorze."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim telefonie."</string>
+ <string name="launch" msgid="4826921505917605463">"Otwórz"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Twój administrator nie zezwala na instalowanie aplikacji pochodzących z nieznanych źródeł."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ten użytkownik nie może instalować nieznanych aplikacji"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ten użytkownik nie może instalować aplikacji"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Zarządzaj aplikacjami"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Brak miejsca"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>. Zwolnij trochę miejsca i spróbuj ponownie."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Nie znaleziono aplikacji"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacji nie znaleziono na liście zainstalowanych programów."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Niedozwolone"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Bieżący użytkownik nie może tego odinstalować."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Błąd"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nie można odinstalować aplikacji."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Odinstaluj aplikację"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Odinstaluj aktualizację"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> jest częścią następującej aplikacji:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Odinstalować tę aplikację?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Chcesz odinstalować tę aplikację dla "<b>"wszystkich"</b>" użytkowników? Ta aplikacja i jej dane zostaną usunięte dla "<b>"wszystkich"</b>" użytkowników na urządzeniu."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Chcesz odinstalować tę aplikację dla użytkownika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte. Dotyczy to wszystkich użytkowników tego urządzenia, również tych korzystających z profilu do pracy."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Aktywne odinstalowania"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Nieudane odinstalowania"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Odinstalowywanie..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Odinstalowuję pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Odinstalowywanie zakończone"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Odinstalowano pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Nie udało się odinstalować."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Nie udało się odinstalować pakietu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nie można odinstalować aktywnej aplikacji do administrowania urządzeniem"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nie można odinstalować aplikacji do administrowania urządzeniem aktywnej dla użytkownika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Niektórzy użytkownicy i niektóre profile wymagają tej aplikacji, a w innych przypadkach została odinstalowana"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ta aplikacja jest potrzebna w Twoim profilu i nie można jej odinstalować."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Administrator urządzenia wymaga tej aplikacji i nie można jej odinstalować."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Zarządzaj aplikacjami do administrowania urządzeniem"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Zarządzaj użytkownikami"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nie można odinstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Podczas analizowania pakietu wystąpił problem."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nowe"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Wszystkie"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Prywatność"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Dostęp do urządzenia"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Ta aktualizacja nie wymaga nowych uprawnień."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odmów"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Więcej informacji"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Odmów mimo to"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> z <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Zezwolić aplikacji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Zawsze zezwalać aplikacji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Tylko przy używaniu aplikacji"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Zawsze"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odmów i nie pytaj ponownie"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"wyłączone: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"wszystkie wyłączone"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"brak wyłączonych"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Zezwól"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacje"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Uprawnienia aplikacji"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Nie pytaj ponownie"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Brak uprawnień"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Dodatkowe uprawnienia"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otwórz informacje o aplikacji"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="few">Jeszcze <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Jeszcze <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Jeszcze <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Jeszcze <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ta aplikacja jest na straszą wersję Androida. Jeśli odmówisz uprawnień, aplikacja może nie działać prawidłowo."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"wykonywanie nieznanych działań"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Dostęp ma: <xliff:g id="COUNT_0">%1$d</xliff:g> z <xliff:g id="COUNT_1">%2$d</xliff:g> aplikacji"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Pokaż systemowe"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ukryj systemowe"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Brak aplikacji"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Ustawienia lokalizacji"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> jest dostawcą usług lokalizacyjnych dla tego urządzenia. Dostęp do danych lokalizacji można zmienić w ustawieniach lokalizacji."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Jeśli nie przyznasz tych uprawnień, podstawowe funkcje urządzenia mogą nie działać prawidłowo."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Narzucone przez zasady"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Dostęp w tle wyłączony przez zasady"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Dostęp w tle włączony przez zasady"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Dostęp na pierwszym planie włączony przez zasady"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolowane przez administratora"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Zawsze"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Tylko przy używaniu aplikacji"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nigdy"</string>
+ <string name="loading" msgid="7811651799620593731">"Ładuję…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Wszystkie uprawnienia"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Inne funkcje aplikacji"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Prośba o pozwolenie"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Wykryto nakładkę ekranową"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Aby zmodyfikować te uprawnienia, musisz najpierw wyłączyć nakładkę ekranową, klikając Ustawienia > Aplikacje"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Otwórz ustawienia"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear nie obsługuje instalowania ani odinstalowywania."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Wybierz, jakie uprawnienia dostępu ma mieć <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacja <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> została zaktualizowana. Wybierz dla niej uprawnienia dostępu."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Anuluj"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Dalej"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nowe uprawnienia"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Aktualne uprawnienia"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Przygotowuję aplikację…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Nieznana"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Ze względów bezpieczeństwa na Twoim tablecie nie można instalować nieznanych aplikacji z tego źródła."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Ze względów bezpieczeństwa na Twoim telewizorze nie można instalować nieznanych aplikacji z tego źródła."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Ze względów bezpieczeństwa na Twoim telefonie nie można instalować nieznanych aplikacji z tego źródła."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Dane na telefonie i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie telefonu lub utratę danych w wyniku jej używania."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Dane na tablecie i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie tabletu lub utratę danych w wyniku jej używania."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Dane na telewizorze i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie telewizora lub utratę danych w wyniku jej używania."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Dalej"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Ustawienia"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalowanie/odinstalowywanie aplikacji na Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-rBR-television/strings.xml b/packages/PackageInstaller/res/values-pt-rBR-television/strings.xml
new file mode 100644
index 0000000..ba6e68f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-rBR-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Negar e não perguntar novamente"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"É possível alterar isso mais tarde em \"Config.\" > \"Apps\""</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostrar apps do sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Permissões do app"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Permissões do app"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Permissões para <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Outras permissões"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Permissões para <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-rBR-watch/strings.xml b/packages/PackageInstaller/res/values-pt-rBR-watch/strings.xml
new file mode 100644
index 0000000..8742c2d
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-rBR-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Negar e não perguntar de novo"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostrar apps do sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Impossível alterar"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Sim"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancelar"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..feb2337
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Instalador do pacote"</string>
+ <string name="next" msgid="3057143178373252333">"Próximo"</string>
+ <string name="install" msgid="5896438203900042068">"Instalar"</string>
+ <string name="done" msgid="3889387558374211719">"Concluído"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalando..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App instalado."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Quer instalar este app? Ele terá acesso a:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Quer instalar este app? Não requer acesso especial."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Quer instalar uma atualização para este app? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Quer instalar uma atualização para este app integrado? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Quer instalar uma atualização para este app existente? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Quer instalar uma atualização para este app integrado? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
+ <string name="install_failed" msgid="6579998651498970899">"O app não foi instalado."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"A instalação do pacote foi bloqueada."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Como o app não é compatível com seu tablet, ele não foi instalado."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Este app não é compatível com sua TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Como o app não é compatível com seu smartphone, ele não foi instalado."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Como o pacote parece ser inválido, o app não foi instalado."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu telefone."</string>
+ <string name="launch" msgid="4826921505917605463">"Abrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Seu administrador não permite a instalação de apps transferidos por download de fontes desconhecidas"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Apps desconhecidos não podem ser instalados por este usuário"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuário não tem permissão para instalar apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gerenciar apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sem espaço"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App não encontrado"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"O app não foi encontrado na lista de apps instalados."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Não permitido"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O usuário atual não tem permissão para executar essa desinstalação."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Não foi possível desinstalar o app."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar atualização"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Quer desinstalar este app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O app e seus dados serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Executando desinstalações"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Falha nas desinstalações"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Desinstalando..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstalação concluída."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Desinstalação malsucedida."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Não é possível desinstalar o app para administrador ativo do dispositivo"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Não é possível desinstalar o app para administrador ativo do dispositivo de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"O app é necessário para alguns usuários ou perfis e foi desinstalado para outros"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Este app é necessário para seu perfil e não pode ser desinstalado."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"O app é exigido pelo administrador do dispositivo e não pode ser desinstalado."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gerenciar apps do administrador do dispositivo"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gerenciar usuários"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ocorreu um problema ao analisar o pacote."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novas"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Todas"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Acesso ao dispositivo"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Esta atualização não requer novas permissões."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Negar"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mais informações"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Negar mesmo assim"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Permitir que o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Sempre permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Apenas ao usar o app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Negar e não perguntar novamente"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desativada(s)"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"todas desativadas"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nenhuma desativada"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permissões do app"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Não perguntar novamente"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Sem permissões"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Outras permissões"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir informações do app"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Este app foi projetado para uma versão anterior do Android. Negar a permissão pode fazer com que ele deixe de funcionar conforme esperado."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"executar uma ação desconhecida"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> apps permitidos"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nenhum app"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Configurações de localização"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> é um provedor de serviços de localização para este dispositivo. O acesso local pode ser modificado nas configurações de localização."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Se você negar essa permissão, recursos básicos do seu dispositivo poderão não funcionar mais como deveriam."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicável por política"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acesso em segundo plano desativado pela política"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acesso em segundo plano ativado pela política"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acesso em primeiro plano ativado pela política"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlada pelo administrador"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Apenas ao usar o app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
+ <string name="loading" msgid="7811651799620593731">"Carregando…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Todas as permissões"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Outros recursos do app"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Solicitação de permissão"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Sobreposição de tela detectada"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Para alterar a configuração dessa permissão, você deve primeiro desativar a sobreposição de tela em \"Config.\" > \"Apps\""</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configurações"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Escolha o que o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> terá permissão de acessar"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"O app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> foi atualizado. Escolha o que esse app terá permissão de acessar."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Novas permissões"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Permissões atuais"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Promovendo app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Desconhecido"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sua segurança, seu tablet não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sua segurança, sua TV não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sua segurança, seu smartphone não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Seu smartphone e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu smartphone ou pela perda de dados que possa resultar do uso desse app."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Seu tablet e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu tablet ou pela perda de dados que possa resultar do uso desse app."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Sua TV e seus dados pessoais estão mais vulneráveis a ataques por apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano à sua TV ou pela perda de dados que possa resultar do uso dese app."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Configurações"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps do Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-rPT-television/strings.xml b/packages/PackageInstaller/res/values-pt-rPT-television/strings.xml
new file mode 100644
index 0000000..206676b
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-rPT-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Recusar e não perguntar novamente"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Pode alterar esta definição mais tarde em Definições > Aplicações"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostrar aplicações do sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Autorizações da aplicação"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Autorizações da aplicação"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Autorizações de <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Autorizações adicionais"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Autorizações de <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-rPT-watch/strings.xml b/packages/PackageInstaller/res/values-pt-rPT-watch/strings.xml
new file mode 100644
index 0000000..e3c9e9f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-rPT-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Recusar e não perguntar nov."</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostrar aplicações do sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Não pode ser alterado"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Sim"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancelar"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..c380839
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Programa de instalação do pacote"</string>
+ <string name="next" msgid="3057143178373252333">"Seguinte"</string>
+ <string name="install" msgid="5896438203900042068">"Instalar"</string>
+ <string name="done" msgid="3889387558374211719">"Concluído"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
+ <string name="installing" msgid="8613631001631998372">"A instalar..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"A instalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplicação instalada."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Pretende instalar esta aplicação? Terá acesso a:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Pretende instalar esta aplicação? Não requer qualquer acesso especial."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Pretende instalar uma atualização para a aplicação existente? Os dados existentes não serão perdidos. A aplicação atualizada terá acesso a:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Pretende instalar uma atualização para a aplicação existente? Os dados existentes não serão perdidos. A aplicação atualizada terá acesso a:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Pretende instalar uma atualização para a aplicação existente? Os dados existentes não serão perdidos. Não é necessário um acesso específico."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Pretende instalar uma atualização para a aplicação integrada? Os dados existentes não serão perdidos. Não é necessário um acesso específico."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplicação não instalada."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Foi bloqueada a instalação do pacote."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"A aplicação não foi instalada porque o pacote entra em conflito com um pacote existente."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"A aplicação não foi instalada porque não é compatível com o seu tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta aplicação não é compatível com a sua TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"A aplicação não foi instalada porque não é compatível com o seu telemóvel."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"A aplicação não foi instalada porque o pacote parece ser inválido."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> no tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Não foi possível instalar o <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> no telemóvel."</string>
+ <string name="launch" msgid="4826921505917605463">"Abrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"O gestor não permite a instalação de aplicações obtidas de fontes desconhecidas"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este utilizador não pode instalar aplicações desconhecidas"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este utilizador não tem permissão para instalar aplicações"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gerir aplicações"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sem espaço"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Liberte algum espaço e tente novamente."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplicação não encontrada"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"A aplicação não foi encontrada na lista de aplicações instaladas."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Não autorizado"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O utilizador atual não tem autorização para efetuar esta desinstalação."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Não foi possível desinstalar a aplicação."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar a aplicação"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar atualização"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> faz parte da seguinte aplicação:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Pretende desinstalar esta aplicação?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Pretende desinstalar esta aplicação para "<b>"todos"</b>" os utilizadores? A aplicação e os respetivos dados serão removidos de "<b>"todos"</b>" os utilizadores do dispositivo."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Pretende desinstalar esta aplicação para o utilizador <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos. Esta ação afeta todos os utilizadores deste dispositivo, incluindo os que têm perfis de trabalho."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstalações em execução"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstalações com falha"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"A desinstalar..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"A desinstalar a aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstalação concluída."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"A aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> foi desinstalada"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Desinstalação sem êxito."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Falha ao desinstalar a aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Não é possível desinstalar a aplicação de administração de dispositivos ativa"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Não é possível desinstalar a aplicação de administração de dispositivos ativa para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Esta aplicação é necessária para alguns utilizadores ou perfis e foi desinstalada para outros"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"O perfil necessita desta aplicação e não é possível desinstalá-la."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Esta aplic. é exigida pelo gestor do disp. e não pode ser desinstalada."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gerir aplicações de administração de dispositivos"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gerir utilizadores"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ocorreu um problema ao analisar o pacote."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novas"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Todas"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Acesso ao Dispositivo"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Esta atualização não requer novas permissões."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Recusar"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mais informações"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Recusar mesmo assim"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Pretende permitir à(ao) <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Pretende permitir que a aplicação <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g> sempre?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Apenas ao utilizar a aplicação"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Recusar e não perguntar novamente"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desativadas"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"todas desativadas"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nenhuma desativada"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicações"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permissões da aplicação"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Não perguntar novamente"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Sem autorizações"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Autorizações adicionais"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir informações da aplicação"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Mais <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicação foi concebida para uma versão mais antiga do Android. Negar autorização pode fazer com que deixe de funcionar como pretendido."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"executar uma ação desconhecida"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicações autorizadas"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Sem aplicações"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Definições de localização"</string>
+ <string name="location_warning" msgid="8778701356292735971">"O <xliff:g id="APP_NAME">%1$s</xliff:g> é um fornecedor de serviços de localização para este dispositivo. É possível modificar o acesso à localização a partir das definições de localização."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Se negar esta autorização, as funcionalidades básicas do seu dispositivo podem deixar de funcionar corretamente."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Imposta pela política"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acesso em segundo plano desativado pela política"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acesso em segundo plano ativado pela política"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acesso em primeiro plano ativado pela política"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlado pelo administrador"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Apenas ao utilizar a aplicação"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
+ <string name="loading" msgid="7811651799620593731">"A carregar…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Todas as autorizações"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Outras capacidades de aplicações"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Pedido de autorização"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Sobreposição de ecrã detetada"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Para alterar esta definição de autorização, primeiro tem de desativar a sobreposição do ecrã em Definições > Aplicações"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir definições"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Escolher a que conteúdos permite que o <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> aceda"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"O <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> foi atualizado. Escolha a que conteúdos permite que esta aplicação aceda."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Novas autorizações"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Autorizações atuais"</string>
+ <string name="message_staging" msgid="6151794817691100003">"A preparar a aplicação…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Desconhecido"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sua segurança, o tablet não está autorizado a instalar aplicações desconhecidas a partir desta fonte."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sua segurança, a TV não está autorizada a instalar aplicações desconhecidas a partir desta fonte."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sua segurança, o telemóvel não está autorizado a instalar aplicações desconhecidas a partir desta fonte."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"O seu telemóvel e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados ao telemóvel ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"O seu tablet e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados ao tablet ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"A sua TV e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados à TV ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Definições"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalar/desinstalar aplicações Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-television/strings.xml b/packages/PackageInstaller/res/values-pt-television/strings.xml
new file mode 100644
index 0000000..ba6e68f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Negar e não perguntar novamente"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"É possível alterar isso mais tarde em \"Config.\" > \"Apps\""</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Mostrar apps do sistema"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Permissões do app"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Permissões do app"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Permissões para <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Outras permissões"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Permissões para <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt-watch/strings.xml b/packages/PackageInstaller/res/values-pt-watch/strings.xml
new file mode 100644
index 0000000..8742c2d
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Negar e não perguntar de novo"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Mostrar apps do sistema"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Impossível alterar"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Sim"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Cancelar"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml
new file mode 100644
index 0000000..feb2337
--- /dev/null
+++ b/packages/PackageInstaller/res/values-pt/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Instalador do pacote"</string>
+ <string name="next" msgid="3057143178373252333">"Próximo"</string>
+ <string name="install" msgid="5896438203900042068">"Instalar"</string>
+ <string name="done" msgid="3889387558374211719">"Concluído"</string>
+ <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
+ <string name="installing" msgid="8613631001631998372">"Instalando..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"App instalado."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Quer instalar este app? Ele terá acesso a:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Quer instalar este app? Não requer acesso especial."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Quer instalar uma atualização para este app? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Quer instalar uma atualização para este app integrado? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Quer instalar uma atualização para este app existente? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Quer instalar uma atualização para este app integrado? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
+ <string name="install_failed" msgid="6579998651498970899">"O app não foi instalado."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"A instalação do pacote foi bloqueada."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Como o app não é compatível com seu tablet, ele não foi instalado."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Este app não é compatível com sua TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Como o app não é compatível com seu smartphone, ele não foi instalado."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Como o pacote parece ser inválido, o app não foi instalado."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu telefone."</string>
+ <string name="launch" msgid="4826921505917605463">"Abrir"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Seu administrador não permite a instalação de apps transferidos por download de fontes desconhecidas"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Apps desconhecidos não podem ser instalados por este usuário"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuário não tem permissão para instalar apps"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gerenciar apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sem espaço"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App não encontrado"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"O app não foi encontrado na lista de apps instalados."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Não permitido"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O usuário atual não tem permissão para executar essa desinstalação."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Não foi possível desinstalar o app."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar atualização"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Quer desinstalar este app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O app e seus dados serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Executando desinstalações"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Falha nas desinstalações"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Desinstalando..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Desinstalação concluída."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Desinstalação malsucedida."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Não é possível desinstalar o app para administrador ativo do dispositivo"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Não é possível desinstalar o app para administrador ativo do dispositivo de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"O app é necessário para alguns usuários ou perfis e foi desinstalado para outros"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Este app é necessário para seu perfil e não pode ser desinstalado."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"O app é exigido pelo administrador do dispositivo e não pode ser desinstalado."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gerenciar apps do administrador do dispositivo"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gerenciar usuários"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ocorreu um problema ao analisar o pacote."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novas"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Todas"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Acesso ao dispositivo"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Esta atualização não requer novas permissões."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Negar"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mais informações"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Negar mesmo assim"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Permitir que o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Sempre permitir que <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Apenas ao usar o app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Negar e não perguntar novamente"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desativada(s)"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"todas desativadas"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nenhuma desativada"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permissões do app"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Não perguntar novamente"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Sem permissões"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Outras permissões"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir informações do app"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Este app foi projetado para uma versão anterior do Android. Negar a permissão pode fazer com que ele deixe de funcionar conforme esperado."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"executar uma ação desconhecida"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> apps permitidos"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nenhum app"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Configurações de localização"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> é um provedor de serviços de localização para este dispositivo. O acesso local pode ser modificado nas configurações de localização."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Se você negar essa permissão, recursos básicos do seu dispositivo poderão não funcionar mais como deveriam."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicável por política"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acesso em segundo plano desativado pela política"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acesso em segundo plano ativado pela política"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acesso em primeiro plano ativado pela política"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlada pelo administrador"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Apenas ao usar o app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
+ <string name="loading" msgid="7811651799620593731">"Carregando…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Todas as permissões"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Outros recursos do app"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Solicitação de permissão"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Sobreposição de tela detectada"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Para alterar a configuração dessa permissão, você deve primeiro desativar a sobreposição de tela em \"Config.\" > \"Apps\""</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configurações"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Escolha o que o app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> terá permissão de acessar"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"O app <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> foi atualizado. Escolha o que esse app terá permissão de acessar."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Novas permissões"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Permissões atuais"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Promovendo app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Desconhecido"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sua segurança, seu tablet não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sua segurança, sua TV não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sua segurança, seu smartphone não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Seu smartphone e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu smartphone ou pela perda de dados que possa resultar do uso desse app."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Seu tablet e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu tablet ou pela perda de dados que possa resultar do uso desse app."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Sua TV e seus dados pessoais estão mais vulneráveis a ataques por apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano à sua TV ou pela perda de dados que possa resultar do uso dese app."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Configurações"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps do Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ro-television/strings.xml b/packages/PackageInstaller/res/values-ro-television/strings.xml
new file mode 100644
index 0000000..4f8992f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ro-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Respingeți și nu se mai întreabă"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Puteți modifica permisiunile ulterior din Setări > Aplicații"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Afișează aplicațiile de sistem"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Permisiuni aplicații"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Permisiuni aplicații"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Permisiuni pentru <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Permisiuni suplimentare"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Permisiuni pentru <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ro-watch/strings.xml b/packages/PackageInstaller/res/values-ro-watch/strings.xml
new file mode 100644
index 0000000..ea699f3
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ro-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Respingeți; nu se mai întreabă"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Afișează aplicațiile de sistem"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Nu se poate modifica"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Da"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Anulați"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml
new file mode 100644
index 0000000..3b13dab3
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ro/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Program de instalare a pachetelor"</string>
+ <string name="next" msgid="3057143178373252333">"Înainte"</string>
+ <string name="install" msgid="5896438203900042068">"Instalați"</string>
+ <string name="done" msgid="3889387558374211719">"Terminat"</string>
+ <string name="cancel" msgid="8360346460165114585">"Anulați"</string>
+ <string name="installing" msgid="8613631001631998372">"În curs de instalare..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Se instalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplicație instalată."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Doriți să instalați această aplicație? Aceasta va avea acces la:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Doriți să instalați această aplicație? Aplicația nu solicită un acces special."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Doriți să instalați o actualizare pentru această aplicație existentă? Datele existente nu vor fi pierdute. Aplicația actualizată va avea acces la:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Doriți să instalați o actualizare pentru această aplicație încorporată? Datele existente nu vor fi pierdute. Aplicația actualizată va avea acces la:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Doriți să instalați o actualizare pentru această aplicație existentă? Datele existente nu vor fi pierdute. Actualizarea nu are nevoie de acces special."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Doriți să instalați o actualizare pentru această aplicație încorporată? Datele existente nu vor fi pierdute. Actualizarea nu are nevoie de acces special."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplicația nu este instalată."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Instalarea pachetului a fost blocată."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplicația nu a fost instalată deoarece pachetul intră în conflict cu un pachet existent."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplicația nu a fost instalată deoarece nu este compatibilă cu tableta dvs."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Această aplicație nu este compatibilă cu televizorul dvs."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplicația nu a fost instalată deoarece nu este compatibilă cu telefonul dvs."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplicația nu a fost instalată deoarece se pare că pachetul este nevalid."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe tableta dvs."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe televizor."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe telefonul dvs."</string>
+ <string name="launch" msgid="4826921505917605463">"Deschideți"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratorul nu permite instalarea aplicațiilor obținute din surse necunoscute"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aplicațiile necunoscute nu pot fi instalate de acest utilizator"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Acest utilizator nu are permisiunea să instaleze aplicații"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Gestionați aplicații"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Spațiu de stocare insuficient"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată. Eliberați spațiu și încercați din nou."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplicația nu a fost găsită"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplicația nu a fost găsită în lista de aplicații instalate."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nu are permisiune"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Utilizatorul actual nu are permisiune pentru a face această dezinstalare."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Eroare"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplicația nu a putut fi dezinstalată."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Dezinstalați aplicația"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Dezinstalați actualizarea"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">" <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> face parte din următoarea aplicație:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Doriți să dezinstalați această aplicație?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Doriți să dezinstalați această aplicație pentru "<b>"toți"</b>" utilizatorii? Aplicația și datele acesteia vor fi eliminate de la "<b>"toți"</b>" utilizatorii de pe acest dispozitiv."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Dezinstalați această aplicație pentru utilizatorul <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate. Această acțiune va afecta toți utilizatorii dispozitivului, inclusiv pe cei cu profiluri de serviciu."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Dezinstalări în curs"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Dezinstalări nereușite"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"În curs de dezinstalare..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Se dezinstalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Dezinstalare finalizată."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a fost dezinstalat"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Dezinstalare nefinalizată."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nu a putut fi dezinstalată."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nu se poate dezinstala aplicația activă de administrare a dispozitivului"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nu se poate dezinstala aplicația activă de administrare a dispozitivului pentru <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplicația este necesară unor utilizatori sau profiluri și a fost dezinstalată pentru alții"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Aplicația este necesară pentru profilul dvs. și nu poate fi dezinstalată."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Aplicație necesară administratorului dispozitivului. Nu poate fi dezinstalată."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Gestionați aplicațiile de administrare dispozitiv"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Gestionați utilizatorii"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi dezinstalată."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"A apărut o problemă la analizarea pachetului."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Noi"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Toate"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Confidențialitate"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Acces la dispozitiv"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Această actualizare nu necesită permisiuni noi."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuzați"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mai multe informații"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Nu permiteți oricum"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> din <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Permiteți <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> să <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Permiteți întotdeauna <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> să <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Doar în timp ce folosiți aplicația"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Întotdeauna"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Respingeți și nu se mai întreabă"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> dezactivate"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"toate dezactivate"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"niciuna dezactivată"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permiteți"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicații"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Permisiuni pentru aplicație"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Nu mai întreba"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Fără permisiuni"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Permisiuni suplimentare"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Deschideți informațiile despre aplicații"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="few">Încă <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Încă <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">Încă <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Această aplicație a fost creată pentru o versiune Android mai veche. Dacă nu acordați permisiunea, este posibil ca aceasta să nu mai funcționeze corespunzător."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"efectuează o acțiune necunoscută"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> din <xliff:g id="COUNT_1">%2$d</xliff:g> aplicații au această permisiune"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Afișați aplicațiile de sistem"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ascundeți aplicațiile de sistem"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Nicio aplicație"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Setări privind locația"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> este un furnizor de servicii de localizare pentru acest dispozitiv. Accesul la locație poate fi modificat din setările privind locația."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Dacă refuzați această permisiune, este posibil ca funcțiile de bază ale dispozitivului să nu mai funcționeze corespunzător."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicată conform politicii"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acces la fundal dezactivat de politică"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acces la fundal activat de politică"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acces la prim-plan activat de politică"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlat de administrator"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Întotdeauna"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Doar în timp ce folosiți aplicația"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Niciodată"</string>
+ <string name="loading" msgid="7811651799620593731">"Se încarcă..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Toate permisiunile"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Alte funcții ale aplicației"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Solicitare de permisiune"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"S-a detectat suprapunerea pe ecran"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Ca să schimbați această setare pentru permisiuni, mai întâi trebuie să dezactivați suprapunerea pe ecran din Setări > Aplicații"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Deschideți setările"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Acțiunile Instalați/Dezinstalați nu sunt acceptate pe Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Alegeți ce va putea accesa <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplicația <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> a fost actualizată. Alegeți ce va putea accesa această aplicație."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Anulați"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Continuați"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Permisiuni noi"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Permisiuni actuale"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Se pregătește aplicația…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Necunoscut"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Din motive de securitate, tableta dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Din motive de securitate, televizorul dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Din motive de securitate, telefonul dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonul și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați aplicația, acceptați că sunteți singura persoană responsabilă pentru deteriorarea telefonului sau pentru pierderea datelor, care pot avea loc în urma utilizării acesteia."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tableta și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați aplicația, acceptați că sunteți singura persoană responsabilă pentru deteriorarea tabletei sau pentru pierderea datelor, care pot avea loc în urma utilizării acesteia."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Televizorul și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați această aplicație, acceptați că sunteți singura persoană responsabilă pentru deteriorarea televizorului sau pentru pierderea datelor, care pot avea loc în urma utilizării acesteia."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuați"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Setări"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Se (dez)instalează aplicațiile Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-round-watch/dimens.xml b/packages/PackageInstaller/res/values-round-watch/dimens.xml
new file mode 100644
index 0000000..fa36464
--- /dev/null
+++ b/packages/PackageInstaller/res/values-round-watch/dimens.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Dimens for dialog layouts -->
+ <dimen name="diag_button_size">48dp</dimen>
+ <dimen name="diag_preferred_padding">@dimen/screen_percentage_15</dimen>
+ <dimen name="diag_button_padding_horizontal">@dimen/screen_percentage_15</dimen>
+ <dimen name="diag_button_padding_bottom">@dimen/screen_percentage_12</dimen>
+ <dimen name="diag_icon_margin_top">@dimen/screen_percentage_10</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ru-television/strings.xml b/packages/PackageInstaller/res/values-ru-television/strings.xml
new file mode 100644
index 0000000..e105f92
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ru-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Запретить и больше не спрашивать"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Чтобы изменить разрешения, откройте \"Настройки\" и выберите \"Приложения\"."</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Показать системные приложения"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Разрешения приложений"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Разрешения приложений"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Разрешения (<xliff:g id="PERMISSION">%1$s</xliff:g>)"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Ещё разрешения"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Разрешения (<xliff:g id="PERMISSION">%1$s</xliff:g>)"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ru-watch/strings.xml b/packages/PackageInstaller/res/values-ru-watch/strings.xml
new file mode 100644
index 0000000..f58db32
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ru-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Запретить и не спрашивать"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Показать системные приложения"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Нельзя изменить"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Да"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Отмена"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
new file mode 100644
index 0000000..9ffdf4a
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Установщик пакетов"</string>
+ <string name="next" msgid="3057143178373252333">"Далее"</string>
+ <string name="install" msgid="5896438203900042068">"Установить"</string>
+ <string name="done" msgid="3889387558374211719">"Готово"</string>
+ <string name="cancel" msgid="8360346460165114585">"Отмена"</string>
+ <string name="installing" msgid="8613631001631998372">"Установка..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Устанавливаем <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Приложение установлено."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Хотите ли вы установить это приложение? Оно получит следующие разрешения:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Это приложение не требует специальных разрешений. Установить его?"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Хотите установить обновление для этого приложения? После обновления оно сможет выполнять следующие действия:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Хотите установить обновление для этого приложения? После обновления оно сможет выполнять следующие действия:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Установить обновление этого приложения? На текущих данных это никак не отразится. Специальных прав доступа не требуется."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Установить обновление этого встроенного приложения? На текущих данных это никак не отразится. Специальных прав доступа не требуется."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Приложение не установлено."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Установка пакета заблокирована."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Приложение не установлено, так как оно конфликтует с другим пакетом."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Приложение не установлено, так как оно несовместимо с вашим планшетом."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Приложение несовместимо с вашим телевизором."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Приложение не установлено, так как оно несовместимо с вашим телефоном."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Приложение не установлено, так как его пакет недействителен (например, поврежден)."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" нельзя установить на ваш телевизор."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
+ <string name="launch" msgid="4826921505917605463">"Открыть"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ваш администратор запретил устанавливать приложения из неизвестных источников"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Этот пользователь не может устанавливать неизвестные приложения"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Этому пользователю не разрешено устанавливать приложения"</string>
+ <string name="ok" msgid="3468756155452870475">"ОК"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Управление приложениями"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Недостаточно места"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". Освободите место и повторите попытку."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Приложение не найдено"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Приложения нет в списке установленных."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Действие запрещено"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Этот пользователь не может удалить приложение."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Ошибка"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Не удалось удалить приложение."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Удаление приложения"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Удаление обновления"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> – часть следующего приложения:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Удалить приложение?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Удалить это приложение для "<b>"всех"</b>" пользователей? После этого "<b>"ни один"</b>" пользователь устройства не будет иметь доступа к приложению и связанным с ним данным."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Удалить это приложение из профиля <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Установить исходную версию приложения? Все его данные будут удалены."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Установить исходную версию приложения? Его данные будут удалены из всех профилей устройства, в том числе рабочих."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активные процессы удаления"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ошибки удаления"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Удаление..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Удаление приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Удаление завершено."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" удалено"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Ошибка при удалении."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Не удалось удалить приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Невозможно удалить активное приложение для администрирования устройства"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Невозможно удалить активное приложение для администрирования устройства в профиле <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Это приложение обязательно для некоторых пользователей или профилей."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Это приложение обязательно для вашего профиля. Его нельзя удалить."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Это приложение указано администратором как обязательное. Его нельзя удалить."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Настроить приложения для администрир. устройства"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Управление пользователями"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Не удалось удалить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ошибка при синтаксическом анализе пакета."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Новые"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Все"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Личные данные"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Доступ к устройству"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Установка этого обновления не требует новых разрешений."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Отклонить"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Подробнее"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Все равно запретить"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> из <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Разрешить приложению <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Всегда разрешать приложению \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Когда открыто приложение"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Всегда"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Запретить и больше не спрашивать"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"отключено: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"все отключены"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"все включены"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Разрешить"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Приложения"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Разрешения приложений"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Больше не спрашивать"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Нет разрешений"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Ещё разрешения"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"О приложении"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Это приложение было разработано для более ранней версии Android. Отзыв разрешения может вызвать неполадки в работе."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"выполняет неизвестные действия"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Приложений с разрешением: <xliff:g id="COUNT_0">%1$d</xliff:g> из <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Показать системные процессы"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Скрыть системные процессы"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Нет приложений"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Настройки геоданных"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> является поставщиком услуг геолокации для этого устройства. Вы можете изменить параметры доступа в настройках геоданных."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Если вы отключите это разрешение, основные функции устройства могут работать неправильно."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"В соответствии с политикой"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Доступ в фоновом режиме отключен в соответствии с правилами."</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Доступ в фоновом режиме включен в соответствии с правилами."</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Активный режим включен в соответствии с правилами."</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролируется администратором"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Всегда"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Когда открыто приложение"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Никогда"</string>
+ <string name="loading" msgid="7811651799620593731">"Загрузка…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Все разрешения"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Что ещё может приложение"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Запрос разрешений"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Показ поверх других окон"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Чтобы предоставить или отменить разрешение, сначала отключите показ поверх других окон. Для этого нажмите \"Настройки > Приложения\"."</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Открыть настройки"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Установка и удаление не поддерживаются на Android Wear"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Выберите разрешения для приложения <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Приложение <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> обновлено. Выберите разрешения для него."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Отмена"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Далее"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Новые разрешения"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Имеющиеся разрешения"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Подождите…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Неизвестное приложение"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"В целях безопасности ваш планшет блокирует установку приложений из неизвестных источников."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"В целях безопасности ваш телевизор блокирует установку приложений из неизвестных источников."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"В целях безопасности ваш телефон блокирует установку приложений из неизвестных источников."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ваши личные данные и данные телефона более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы соглашаетесь с тем, что несете полную ответственность за любой ущерб, нанесенный телефону, и потерю данных, связанные с использованием этого приложения."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ваши личные данные и данные планшета более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы соглашаетесь с тем, что несете полную ответственность за любой ущерб, нанесенный планшету, и потерю данных, связанные с использованием этого приложения."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ваши личные данные и данные телевизора более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы соглашаетесь с тем, что несете полную ответственность за любой ущерб, нанесенный телевизору, и потерю данных, связанные с использованием этого приложения."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Продолжить"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Настройки"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Установка/удаление приложений для Android Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-si-television/strings.xml b/packages/PackageInstaller/res/values-si-television/strings.xml
new file mode 100644
index 0000000..2ac8d8b
--- /dev/null
+++ b/packages/PackageInstaller/res/values-si-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"ප්රතික්ෂේප කරන්න, නැවත අසන්න එපා"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"ඔබට මෙය පසුව සැකසීම් > යෙදුම් තුළ වෙනස් කළ හැකිය"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"පද්ධති යෙදුම් පෙන්වන්න"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"යෙදුම් අවසර"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"යෙදුම් අවසර"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> අවසර"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"අතිරේක අවසර"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> අවසර"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-si-watch/strings.xml b/packages/PackageInstaller/res/values-si-watch/strings.xml
new file mode 100644
index 0000000..c5d9ae4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-si-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ප්රතික්ෂේප කරන්න, නැවත අසන්න එපා"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"පද්ධති යෙදුම් පෙන්වන්න"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"වෙනස් කළ නොහැකිය"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ඔව්"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"අවලංගු කර."</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml
new file mode 100644
index 0000000..18fc840
--- /dev/null
+++ b/packages/PackageInstaller/res/values-si/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"පැකේජ ස්ථාපනකරු"</string>
+ <string name="next" msgid="3057143178373252333">"මීලඟ"</string>
+ <string name="install" msgid="5896438203900042068">"ස්ථාපනය"</string>
+ <string name="done" msgid="3889387558374211719">"හරි"</string>
+ <string name="cancel" msgid="8360346460165114585">"අවලංගු කරන්න"</string>
+ <string name="installing" msgid="8613631001631998372">"ස්ථාපනය කරමින්…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ස්ථාපනය කරමින්…"</string>
+ <string name="install_done" msgid="3682715442154357097">"යෙදුම ස්ථාපනය කරන ලදි."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"ඔබට මෙම යෙදුම ස්ථාපනය කිරීමට අවශ්යද? පහත ඒවා වෙත එයට ප්රවේශය ලැබෙනු ඇත:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"මෙම යෙදුම ස්ථාපනය කිරීමට ඔබට අවශ්යද? වෙනත් විශේෂ ප්රවේශයක් එයට අවශ්ය නොවෙයි."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"දැනට පවතින මෙම යෙදුමට යාවත්කාලීනයක් ස්ථාපනය කිරීමට ඔබට අවශ්යද? ඔබගේ පවතින දත්ත නැති නොවේ. යාවත්කාලීන කළ යෙදුම පිවිසීම ලබා ගනී:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ඔබට මෙම තිළැලි යෙදුමට යාවත්කාලීනය ස්ථාපනය කිරීමට අවශ්යද? ඔබගේ දැනට පවතින දත්ත නැති නොවේ. යාවත්කාලීන කරන ලද යෙදුම පහත සඳහා ප්රවේශය ලබාගනු ඇත:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"මෙම පවතින යෙදුමට යාවත්කාලීනයක් ස්ථාපනය කිරීමට ඔබට අවශ්යද? ඔබගේ පවතින දත්ත නැති නොවේ. එයට විශේෂ ප්රවේශයක් අවශ්ය නොවේ."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"පවතින මෙම යෙදුමට යාවත්කාලීනයක් ස්ථාපනය කිරීමට ඔබට අවශ්යද? ඔබගේ පවතින දත්ත නැති නොවේ. එයට විශේෂ ප්රවේශයක් අවශ්ය නොවේ."</string>
+ <string name="install_failed" msgid="6579998651498970899">"යෙදුම ස්ථාපනය කරේ නැත."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"මෙම පැකේජය ස්ථාපනය කිරීම අවහිර කරන ලදි."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"පැකේජය දැනට පවතින පැකේජයක් සමග ගැටෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"යෙදුම ඔබේ ටැබ්ලට් පරිගණකය සමග නොගැළපෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"මෙම යෙදුම ඔබගේ රූපවාහිනිය හා නොගැළපේ."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"යෙදුම ඔබේ දුරකථනය සමග නොගැළපෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"පැකේජය වලංගු නොවන බවක් පෙනෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ඔබගේ ටැබ්ලටයේ <xliff:g id="APP_NAME">%1$s</xliff:g> ස්ථාපනය කළ නොහැක."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> මෙම රූපවාහිනියෙහි ස්ථාපනය කළ නොහැක."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> දුරකථනයට ස්ථාපිත කිරීමට නොහැකි විය."</string>
+ <string name="launch" msgid="4826921505917605463">"විවෘත කරන්න"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"නාඳුනන මූලයන් වෙතින් ලබාගත් යෙදුම් ස්ථාපනය කිරීමට ඔබගේ පරිපාලකයා ඉඩ නොදේ"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"මෙම පරිශීලකයා මඟින් නොදන්නා යෙදුම් ස්ථාපනය කළ නොහැක"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"මෙම පරිශීලකයාට යෙදුම් ස්ථාපනය කිරීමට අවසර නැත"</string>
+ <string name="ok" msgid="3468756155452870475">"හරි"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"යෙදුම් කළමනාකරණය කරන්න"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ඉඩ නොමැත"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ස්ථාපිත කිරීමට නොහැකි විය. ඉඩ පොඩ්ඩක් නිදහස් කොට නැවත උත්සාහ කරන්න."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"යෙදුම හමුවී නැත"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ස්ථාපිත යෙදුම් ලැයිස්තුවේ යෙදුම සොයා ගත නොහැකි විය."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ඉඩ නොදෙයි"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"වත්මන් පරිශීලකයාට මෙම අස්ථාපනය සිදු කිරීමට ඉඩ නොදේ."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"දෝෂය"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"යෙදුම අස්ථාපනය කළ නොහැකි විය."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"යෙදුම අස්ථාපනය කරන්න"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"යාවත්කාලිනය අස්ථාපනය කරන්න"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> පහත යෙදුමේ කොටසකි:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"ඔබට මෙම යෙදුම අස්ථාපනය කිරීමට අවශ්යද?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222"><b>"සියලු"</b>" පරිශීලකයන් සඳහා මෙම යෙදුම අස්ථාපනය කිරීමට ඔබට අවශ්යද? උපාංගයෙහි "<b>"සියලු"</b>" පරිශීලකයන් සඳහා යෙදුම සහ එහි දත්ත ඉවත්වනු ඇත."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> පරිශීලකයා සඳහා මෙම යෙදුම අස්ථාපනය කිරීමට ඔබට අවශ්යයද?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"මෙම යෙදුම කර්මාන්ත ශාලා අනුවාදයක් සමගින් ප්රතිස්ථාපනය කරන්නද? සියලු දත්ත ඉවත් කරනු ඇත."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"මෙම යෙදුම කර්මාන්ත ශාලා අනුවාදයක් සමගින් ප්රතිස්ථාපනය කරන්නද? සියලු දත්ත ඉවත් කරනු ඇත. මෙය කාර්යාල පැතිකඩවල් සහිත අය ඇතුළුව, මෙම උපාංගයෙහි සියලු පරිශීලකයන් වෙත බලපානු ඇත."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"අස්ථාපන ධාවනය කරමින්"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"අසාර්ථක වූ අස්ථාපන"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"අස්ථාපනය කරමින්…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරමින්…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"අස්ථාපනය අවසන්."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරන ලදී"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"අස්ථාපිත විම අසාර්ථකයි."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කිරීම සාර්ථකයි."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ක්රියාකාරී උපාංගය පරිපාලක යෙදුම අස්ථාපනය කිරීමට නොහැක"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> සඳහා ක්රියාකාරී උපාංගය පරිපාලක යෙදුම අස්ථාපනය කිරීමට නොහැක"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"මෙම යෙදුම සමහර පරිශීලකයන්ට සහ පැතිකඩවල්වලට අවශ්ය අතර අනෙක් අයට අස්ථාපනය කරන ලදී"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ඔබේ කාර්ය පැතිකඩ සඳහා මෙම යෙදුම අවශ්ය වන අතර අස්ථාපනය කළ නොහැකිය."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ඔබගේ උපාංගයේ පාලකයාට මෙම යෙදුම අවශ්ය වේ එම නිසා අස්ථාපනය කළ නොහැක."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"උපාංග පරිපාලක යෙදුම් කළමනාකරණය කිරීම"</string>
+ <string name="manage_users" msgid="3125018886835668847">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> අස්ථාපනය කල නොහැක."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"පැකේජය විග්රහ කිරීමේදී ගැටළුවක් ඇති විය."</string>
+ <string name="newPerms" msgid="6039428254474104210">"අලුත්"</string>
+ <string name="allPerms" msgid="1024385515840703981">"සියල්ල"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"පෞද්ගලිකත්වය"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"උපාංගය ප්රවේශය"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"මෙම යාවත්කාලිනයට අලුත් අවසරයන් අවශ්ය නොවේ."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ප්රතික්ෂේප කරන්න"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"වැඩිදුර තොරතුරු"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"කෙසේ වෙතත් ප්රතික්ෂේප කරන්න"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> න් <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ට <xliff:g id="ACTION">%2$s</xliff:g> වෙත ඉඩ දෙන්නද?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"සැම විට <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> හට <xliff:g id="ACTION">%2$s</xliff:g> වෙත ඉඩ දෙන්නද?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"යෙදුම භාවිතා කරන විට පමණි"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"සැම විට"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ප්රතික්ෂේප කරන්න, නැවත අසන්න එපා"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> අබලයි"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"සියල්ල අබලයි"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"කිසිවක් අබල නැත"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ඉඩ දෙන්න"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"යෙදුම්"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"යෙදුම් අවසර"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"නැවත අසන්න එපා"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"අවසර නොමැත"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"අතිරේක අවසර"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"යෙදුම් තොරතුරු විවෘත කරන්න"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">.තව <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">.තව <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"මෙම යෙදුම නිර්මාණය කර ඇත්තේ Android වල පැරණි අනුවාදයකට වේ. අවසර නොදීම මඟින් එය බලාපොරොත්තු වන ආකාරයට වැඩ නොකිරීමට හැක."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"නොදන්නා ක්රියාවක් සිදු කරන්න"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"යෙදුම් <xliff:g id="COUNT_1">%2$d</xliff:g> න් <xliff:g id="COUNT_0">%1$d</xliff:g> කට ඉඩ දෙන ලදි"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"පද්ධතිය පෙන්වන්න"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"පද්ධතිය සඟවන්න"</string>
+ <string name="no_apps" msgid="1965493419005012569">"යෙදුම් නොමැත"</string>
+ <string name="location_settings" msgid="1774875730854491297">"ස්ථාන සැකසීම්"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> මෙම උපාංගය සඳහා ස්ථාන සේවාවන් සපයන්නෙකු වේ. ස්ථාන ප්රවේශය ස්ථාන සැකසීම් වෙතින් වෙනස් කළ හැක."</string>
+ <string name="system_warning" msgid="7103819124542305179">"ඔබ මෙම අවසරය ප්රතික්ෂේප කරන්නේ නම්, සමහර යෙදුම් බලාපොරොත්තු පරිදි ක්රියා නොකරනු ඇත."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ප්රතිපත්තිය මඟින් බලාත්මක කරයි"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"පසුබිම් ප්රවේශය ප්රතිපත්තිය මගින් අබල කර ඇත"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"පසුබිම් ප්රවේශය ප්රතිපත්තිය මගින් සබල කර ඇත"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"පෙරබිම් ප්රවේශය ප්රතිපත්තිය මගින් සබල කර ඇත"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"පරිපාලක විසින් පාලනය කෙරේ"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"සැම විට"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"යෙදුම භාවිතා කරන විට පමණි"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"කිසි විටක නැත"</string>
+ <string name="loading" msgid="7811651799620593731">"පූරණය කරමින්…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"සියලු අවසර"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"වෙනත් යෙදුම් හැකියාවන්"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"අවසර ඉල්ලීම"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"තිර උඩැතිරියක් අනාවරණය කරන ලදි"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"මෙම අවසර සැකසීම වෙනස් කිරීම සඳහා, ඔබට මුලින්ම සැකසීම් > යෙදුම් වෙතින් තිර උඩැතිරිය අක්රිය කර යුතුයි"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"සැකසීම් විවෘත කරන්න"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear මත ස්ථාපන/අස්ථාපනය ක්රියා සහාය දක්වන්නේ නැත."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> හට පිවිසීමට ඉඩ දෙන දේ තෝරන්න"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> යාවත්කාලීන කර ඇත. මෙම යෙදුමට පිවිසීමට ඉඩ දෙන දේ තෝරන්න."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"අවලංගු කරන්න"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"දිගටම කර ගෙන යන්න"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"නව අවසර"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"වත්මන් අවසර"</string>
+ <string name="message_staging" msgid="6151794817691100003">"යෙදුම වේදිකාගත කරමින්..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"නොදනී"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ආරක්ෂාව සඳහා, ඔබගේ ටැබ්ලටය මෙම මුලාශ්රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ආරක්ෂාව සඳහා, ඔබගේ රූපවාහිනිය මෙම මුලාශ්රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ආරක්ෂාව සඳහා, ඔබගේ දුරකථනය මෙම මුලාශ්රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ඔබගේ දුරකථනය සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ දුරකථනය සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ඔබගේ ටැබ්ලට් පරිගණකය සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ ටැබ්ලට් පරිගණකය සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ඔබගේ TV සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ TV සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"දිගටම කරගෙන යන්න"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"සැකසීම්"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear යෙදුම් ස්ථාපනය/අස්ථාපනය කරමින්"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sk-television/strings.xml b/packages/PackageInstaller/res/values-sk-television/strings.xml
new file mode 100644
index 0000000..15ecdb8
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sk-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Zamietnuť a nabudúce sa nepýtať"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Neskôr to môžete zmeniť v časti Nastavenia > Aplikácie"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Zobraziť systémové aplikácie"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Povolenia aplikácie"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Povolenia aplikácie"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Povolenia – <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Ďalšie povolenia"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Povolenia – <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sk-watch/strings.xml b/packages/PackageInstaller/res/values-sk-watch/strings.xml
new file mode 100644
index 0000000..dc3ce4f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sk-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Zamietnuť a už sa nepýtať"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Zobraziť systémové aplikácie"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Nedá sa zmeniť"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Áno"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Zrušiť"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
new file mode 100644
index 0000000..a27f650
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Nástroj na inštaláciu balíčkov"</string>
+ <string name="next" msgid="3057143178373252333">"Ďalej"</string>
+ <string name="install" msgid="5896438203900042068">"Inštalovať"</string>
+ <string name="done" msgid="3889387558374211719">"Hotovo"</string>
+ <string name="cancel" msgid="8360346460165114585">"Zrušiť"</string>
+ <string name="installing" msgid="8613631001631998372">"Inštaluje sa..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Inštaluje sa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikácia bola nainštalovaná."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Chcete nainštalovať túto aplikáciu? Získa nasledujúce povolenia:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Chcete nainštalovať túto aplikáciu? Nevyžaduje žiadny zvláštny prístup."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Chcete nainštalovať aktualizáciu existujúcej aplikácie? Existujúce údaje sa nestratia. Aktualizovaná aplikácia získa nasledujúce povolenia:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Chcete nainštalovať aktualizáciu tejto integrovanej aplikácie? Existujúce údaje sa nestratia. Aktualizovaná aplikácia získa nasledujúce povolenia:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Chcete nainštalovať aktualizáciu tejto existujúcej aplikácie? Vaše údaje nebudú stratené. Táto akcia nevyžaduje žiadny zvláštny prístup."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Chcete nainštalovať aktualizáciu tejto vstavanej aplikácie? Vaše údaje sa nestratia. Táto akcia nevyžaduje žiadny zvláštny prístup."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikácia nebola nainštalovaná."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Inštalácia balíka bola zablokovaná."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikácia sa nenainštalovala, pretože balík koliduje s existujúcim balíkom."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikácia sa nenainštalovala, pretože nie je kompatibilná s vaším tabletom."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Táto aplikácia nie je kompatibilná s vaším televízorom."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikácia sa nenainštalovala, pretože nie je kompatibilná s vaším telefónom."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikácia sa nenainštalovala, pretože je balík zrejme neplatný."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa do vášho tabletu nepodarilo nainštalovať."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo nainštalovať na vašom televízore."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa do vášho telefónu nepodarilo nainštalovať."</string>
+ <string name="launch" msgid="4826921505917605463">"Otvoriť"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Váš správca zakázal inštaláciu aplikácií z neznámych zdrojov"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Tento používateľ nemôže inštalovať neznáme aplikácie"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Tento používateľ nemá povolené inštalovať aplikácie"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Spravovať aplikácie"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nedostatok miesta"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo nainštalovať. Uvoľnite miesto v pamäti a skúste to znova."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikácia sa nenašla"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikáciu sa nepodarilo nájsť v zozname nainštalovaných aplikácií."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nie je povolené"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Aktuálny používateľ nemá na odinštalovanie povolenie."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Chyba"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikáciu nie je možné odinštalovať."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Odinštalovať aplikáciu"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Odinštalovať aktualizáciu"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"Aktivita <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je súčasťou nasledujúcej aplikácie:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Chcete túto aplikáciu odinštalovať?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Chcete odinštalovať túto aplikáciu pre "<b>"všetkých"</b>" používateľov? Aplikácia a jej údaje sa odstránia z tohto zariadenia pre "<b>"všetkých"</b>" používateľov."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Chcete túto aplikáciu odinštalovať pre používateľa <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Nahradiť túto aplikáciu továrenskou verziou? Všetky údaje sa odstránia."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Nahradiť túto aplikáciu továrenskou verziou? Všetky údaje sa odstránia. Ovplyvní to všetkých používateľov tohto zariadenia vrátane tých s pracovnými profilmi."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Prebiehajúce odinštalácie"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neúspešné odinštalácie"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Prebieha odinštalovanie..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Prebieha odinštalovanie balíčka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Odinštalovanie bolo dokončené."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Balíček <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odinštalovaný"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Odinštalovanie bolo neúspešné."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Odinštalovanie balíčka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa nepodarilo."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktívna aplikácia na správu zariadenia sa nedá odinštalovať"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Aktívna aplikácia na správu zariadenia sa v prípade používateľa <xliff:g id="USERNAME">%1$s</xliff:g> nedá odinštalovať"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Táto aplikácia sa vyžaduje v prípade niektorých používateľov či profilov a v prípade iných zase bola odinštalovaná"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Táto aplikácia sa vyžaduje pre váš profil a nemôžete ju odinštalovať."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Túto aplikáciu vyžaduje správca vášho zariadenia a nie je ju možné odinštalovať."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Spravovať aplikácie na ovládanie zariadenia"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Spravovať používateľov"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo odinštalovať."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Pri analýze balíka sa vyskytol problém."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nové"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Všetko"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Ochrana súkromia"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Prístup k zariadeniu"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Táto aktualizácia nevyžaduje žiadne nové povolenia."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odmietnuť"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Ďalšie informácie"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Zamietnuť"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> z <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vždy povoliť aplikácii <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Iba počas používania aplikácie"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Vždy"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Zamietnuť a nabudúce sa nepýtať"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"deaktivované (<xliff:g id="COUNT">%1$d</xliff:g>)"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"všetky sú zakázané"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"žiadne nie sú zakázané"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Povoliť"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikácie"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Povolenia aplikácií"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Nabudúce sa nepýtať"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Žiadne povolenia"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Ďalšie povolenia"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvoriť informácie o aplikácii"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> ďalšie</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> ďalšieho</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ďalších</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ďalšie</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Táto aplikácia bola navrhnutá pre staršiu verziu systému Android. Odmietnutie povolenia môže spôsobiť, že nebude optimálne fungovať."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"umožňuje vykonať neznámu akciu"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Povolené <xliff:g id="COUNT_0">%1$d</xliff:g> z <xliff:g id="COUNT_1">%2$d</xliff:g> aplikácií"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Zobraziť systémové aplikácie"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Skryť systémové aplikácie"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Žiadne aplikácie"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Nastavenia polohy"</string>
+ <string name="location_warning" msgid="8778701356292735971">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je poskytovateľ služieb určovania polohy tohto zariadenia. Prístup k polohe môžete upraviť v nastaveniach polohy."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ak toto povolenie zamietnete, základné funkcie vášho zariadenia nemusia pracovať podľa očakávaní."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Vynútené pravidlom"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Prístup na pozadí je zakázaný pravidlom"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Prístup na pozadí je povolený pravidlom"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Prístup na popredí je povolený pravidlom"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Ovládané správcom"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Vždy"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Iba počas používania aplikácie"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nikdy"</string>
+ <string name="loading" msgid="7811651799620593731">"Načítava sa…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Všetky povolenia"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Ďalšie možnosti aplikácie"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Žiadosť o povolenie"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Bolo zistené prekrytie obrazovky"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Ak chcete zmeniť nastavenie tohto povolenia, musíte najprv v časti Nastavenia > Aplikácie vypnúť prekrytie obrazovky"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Otvoriť nastavenia"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Systém Wear nepodporuje akciu inštalácie/odinštalovania."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Vyberte, k čomu môže pristupovať aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikácia <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> bola aktualizovaná. Vyberte, k čomu môže pristupovať."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Zrušiť"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Pokračovať"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nové povolenia"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Aktuálne povolenia"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Aplikácia je zavádzaná po etapách…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Neznáma"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Váš tablet nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Váš televízor nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Váš telefón nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Váš telefón a osobné údaje sú náchylnejšie na útok z neznámych aplikácií. Inštalovaním tejto aplikácie súhlasíte, že zodpovedáte za akékoľvek poškodenie vášho telefónu či stratu údajov, ku ktorým môže dôjsť v dôsledku jej použitia."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Váš tablet a osobné údaje sú náchylnejšie na útok z neznámych aplikácií. Inštalovaním tejto aplikácie súhlasíte, že zodpovedáte za akékoľvek poškodenie vášho tabletu či stratu údajov, ku ktorým môže dôjsť v dôsledku jej použitia."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Váš televízor a osobné údaje sú náchylnejšie na útok z neznámych aplikácií. Inštalovaním tejto aplikácie súhlasíte, že zodpovedáte za akékoľvek poškodenie vášho televízora či stratu údajov, ku ktorým môže dôjsť v dôsledku jej použitia."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Pokračovať"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Nastavenia"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Inštalácia/odinštalácia aplikácií Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sl-television/strings.xml b/packages/PackageInstaller/res/values-sl-television/strings.xml
new file mode 100644
index 0000000..3e8e4ea
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sl-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Zavrni in ne sprašuj več"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"To lahko pozneje spremenite v »Nastavitve > Aplikacije«"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Prikaz sistemskih aplikacij"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Dovoljenja za aplikacije"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Dovoljenja za aplikacije"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Dovoljenja za: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Dodatna dovoljenja"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Dovoljenja za: <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sl-watch/strings.xml b/packages/PackageInstaller/res/values-sl-watch/strings.xml
new file mode 100644
index 0000000..906a551
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sl-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Zavrni, ne sprašuj več"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Prikaz sistemskih aplikacij"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Ni mogoče sprem."</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Da"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Prekliči"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
new file mode 100644
index 0000000..4075006
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Namestitveno orodje za paket"</string>
+ <string name="next" msgid="3057143178373252333">"Naprej"</string>
+ <string name="install" msgid="5896438203900042068">"Namesti"</string>
+ <string name="done" msgid="3889387558374211719">"Dokončano"</string>
+ <string name="cancel" msgid="8360346460165114585">"Prekliči"</string>
+ <string name="installing" msgid="8613631001631998372">"Nameščanje …"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Nameščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikacija je nameščena."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Ali želite namestiti to aplikacijo? Imela bo dostop do:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ali želite namestiti to aplikacijo? Poseben dostop ni potreben."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Ali želite namestiti posodobitev te obstoječe aplikacije? Obstoječi podatki ne bodo izgubljeni. Posodobljena aplikacija bo imela dostop do:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ali želite namestiti posodobitev za to vgrajeno aplikacijo? Obstoječi podatki ne bodo izgubljeni. Posodobljena aplikacija bo imela dostop do:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ali želite namestiti posodobitev te obstoječe aplikacije? Obstoječi podatki ne bodo izgubljeni. Za namestitev ne potrebujete posebnega dostopa."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ali želite namestiti posodobitev te vgrajene aplikacije? Obstoječi podatki ne bodo izgubljeni. Za namestitev ne potrebujete posebnega dostopa."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikacija ni nameščena."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Namestitev paketa je bila blokirana."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija ni bila nameščena, ker je paket v navzkrižju z obstoječim paketom."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija ni bila nameščena, ker ni združljiva s tabličnim računalnikom."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ta aplikacija ni združljiva z vašim televizorjem."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija ni bila nameščena, ker ni združljiva s telefonom."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija ni bila nameščena, ker paket verjetno ni veljaven."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v tablični računalnik."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v vašem televizorju."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v telefon."</string>
+ <string name="launch" msgid="4826921505917605463">"Odpri"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Skrbnik ne dovoli nameščanja aplikacij iz neznanih virov."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ta uporabnik nima dovoljenja za nameščanje neznanih aplikacij"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ta uporabnik nima dovoljenja za nameščanje aplikacij"</string>
+ <string name="ok" msgid="3468756155452870475">"V redu"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Upravljaj aplikacije"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Zmanjkalo je prostora"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti. Sprostite prostor in poskusite znova."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacije ni bilo mogoče najti"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacije ni bilo mogoče najti na seznamu nameščenih aplikacij."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ni dovoljeno"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Trenutni uporabnik nima dovoljenja za izvedbo te odstranitve."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Napaka"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikacije ni bilo mogoče odstraniti."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Odstrani aplikacijo"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Odstrani posodobitev"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je del te aplikacije:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Ali želite odstraniti to aplikacijo?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ali želite odstraniti aplikacijo za "<b>"vse"</b>" uporabnike? Aplikacija in njeni podatki bodo odstranjeni iz "<b>"vseh"</b>" uporabnikov v napravi."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ali želite to aplikacijo odstraniti za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki. To vpliva na vse uporabnike te naprave, vključno s tistimi z delovnimi profili."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Odstranitve v teku"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspele odstranitve"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Odstranjevanje ..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Odstranitev je končana."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je bila odstranjena"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Odstranitev ni uspela."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktivne skrbniške aplikacije naprave ni mogoče odstraniti"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Aktivne skrbniške aplikacije za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g> ni mogoče odstraniti"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplikacija je obvezna za nekatere uporabnike/profile in je odstranjena za druge."</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ta aplikacija je potrebna za profil in je ni mogoče odstraniti."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"To aplikacijo zahteva skrbnik naprave in je ni mogoče odstraniti."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Upravljanje skrbniških aplikacij naprave"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Upravljanje uporabnikov"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče odstraniti."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Težava pri razčlenjevanju paketa."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Vse"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Zasebnost"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Dostop do naprave"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Za to posodobitev niso potrebna nova dovoljenja."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Zavrni"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Več informacij"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Vseeno zavrni"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Ali dovolite aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> izvesti to dejanje: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Želite aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> vedno dovoliti to dejanje: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo med uporabo aplikacije"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Vedno"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Zavrni in ne sprašuj več"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"št. onemogočenih: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"vse onemogočeno"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"nič ni onemogočeno"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dovoli"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Dovoljenja za aplikacije"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ne sprašuj več"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Ni dovoljenj"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Dodatna dovoljenja"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Odpri podatke o aplikaciji"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="two">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ta aplikacija je bila zasnovana za starejšo različico sistema Android. Če dovoljenje zavrnete, lahko preneha delovati, kot bi morala."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"izvedba neznanega dejanja"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Dovoljene aplikacije: <xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Prikaz sistemskih aplikacij"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Skrivanje sistemskih aplikacij"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Ni aplikacij"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Nastavitve lokacije"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> je ponudnik lokacijskih storitev za to napravo. Dostop do lokacije je mogoče spremeniti v nastavitvah lokacije."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Če zavrnete to dovoljenje, osnovne funkcije naprave morda ne bodo več delovale, kot bi morale."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Uveljavlja pravilnik"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Dostop iz ozadja je onemogočen s pravilnikom"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Dostop iz ozadja je omogočen s pravilnikom"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Dostop v ospredju je omogočen s pravilnikom"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Nadzira skrbnik"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Vedno"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo med uporabo aplikacije"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Nikoli"</string>
+ <string name="loading" msgid="7811651799620593731">"Nalaganje …"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Vsa dovoljenja"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Druge zmožnosti aplikacije"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Zahteva za dovoljenje"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Zaznano prekrivanje zaslona"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Če želite spremeniti nastavitev tega dovoljenja, morate najprej izklopiti prekrivanje zaslona v »Nastavitve > Aplikacije«"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Odpri nastavitve"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Dejanja namestitve in odstranitve v sistemu Android Wear niso podprta."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Izberite, do česa aplikaciji <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> dovolite dostop"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> je posodobljena. Izberite, do česa tej aplikaciji dovolite dostop."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Prekliči"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Naprej"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nova dovoljenja"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Trenutna dovoljenja"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Priprava aplikacije …"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Neznano"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Vaš tablični računalnik zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Vaš televizor zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Vaš telefon zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Neznane aplikacije lahko resno ogrozijo varnost telefona in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v telefonu, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Neznane aplikacije lahko resno ogrozijo varnost tabličnega računalnika in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v tabličnem računalniku, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Neznane aplikacije lahko resno ogrozijo varnost televizorja in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v televizorju, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Nadaljuj"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Nastavitve"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Nameščanje/odstranjev. aplikacij za Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sq-television/strings.xml b/packages/PackageInstaller/res/values-sq-television/strings.xml
new file mode 100644
index 0000000..d66231c
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sq-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Refuzo dhe mos pyet përsëri"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Këtë mund ta ndryshosh më vonë te Cilësimet > Aplikacionet"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Shfaq aplikacionet e sistemit"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Lejet e aplikacionit"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Lejet e aplikacionit"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Lejet për <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Lejet shtesë"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Lejet për <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sq-watch/strings.xml b/packages/PackageInstaller/res/values-sq-watch/strings.xml
new file mode 100644
index 0000000..772bb7a
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sq-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Refuzoje, mos pyet sërish"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Shfaq aplikacionet e sistemit"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Nuk mund të ndryshohet"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Po"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Anulo"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml
new file mode 100644
index 0000000..8f7e0fc
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sq/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Instaluesi i paketës"</string>
+ <string name="next" msgid="3057143178373252333">"Përpara"</string>
+ <string name="install" msgid="5896438203900042068">"Instalo"</string>
+ <string name="done" msgid="3889387558374211719">"U krye!"</string>
+ <string name="cancel" msgid="8360346460165114585">"Anulo"</string>
+ <string name="installing" msgid="8613631001631998372">"Po instalon…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Po instalon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Aplikacioni u instalua."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Dëshiron ta instalosh këtë aplikacion? Ai do të ketë qasje në:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Dëshiron ta instalosh këtë aplikacion? Nuk kërkon ndonjë qasje të veçantë."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Dëshiron të instalosh një përditësim në këtë aplikacion ekzistues? Të dhënat e tua ekzistuese nuk do të humbin. Aplikacioni i përditësuar do të ketë qasje në:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Dëshiron të instalosh një përditësim në këtë aplikacion të integruar? Të dhënat e tua ekzistuese nuk do të humbin. Aplikacioni i përditësuar do të ketë qasje në:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Dëshiron të instalosh një përditësim të këtij aplikacioni ekzistues? Të dhënat e tua ekzistuese nuk do të humbasin. Aplikacioni nuk kërkon ndonjë qasje të veçantë."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Dëshiron të instalosh një përditësim të këtij aplikacioni ekzistues? Të dhënat e tua ekzistuese nuk do të humbasin. Aplikacioni nuk kërkon ndonjë qasje të veçantë."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Aplikacioni nuk u instalua."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Instalimi paketës u bllokua."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacioni nuk u instalua pasi paketa është në konflikt me një paketë ekzistuese."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacioni nuk u instalua pasi nuk është i përputhet me tabletin tënd."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ky aplikacion është i papërshtatshëm me televizorin tënd."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacioni nuk u instalua pasi nuk përputhet me telefonin tënd."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacioni nuk u instalua pasi paketa duket se nuk është e vlefshme."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej në tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej në televizor."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mundi të instalohej në telefon."</string>
+ <string name="launch" msgid="4826921505917605463">"Hap"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratori nuk lejon instalimin e aplikacioneve nga burime të panjohura."</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aplikacionet e panjohura nuk mund të instalohen nga ky përdorues"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ky përdorues nuk lejohet të instalojë aplikacione"</string>
+ <string name="ok" msgid="3468756155452870475">"Në rregull"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Menaxho aplikacionet"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nuk ka hapësirë"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej. Liro pak hapësirë dhe provo përsëri."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacioni nuk u gjet"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacioni nuk u gjet në listën e aplikacioneve të instaluara."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nuk lejohet"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Përdoruesi aktual nuk lejohet të kryejë këtë çinstalim."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Gabim"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikacioni nuk mund të instalohej."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Çinstalo aplikacionin"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Çinstalo përditësimin"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> është pjesë e aplikacionit të mëposhtëm:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Dëshiron ta çinstalosh këtë aplikacion?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Dëshiron ta çinstalosh këtë aplikacion për "<b>"të gjithë"</b>" përdoruesit? Aplikacioni dhe të dhënat e tij do të hiqen nga "<b>"të gjithë"</b>" përdoruesit e pajisjes."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Dëshiron ta çinstalosh këtë aplikacion për përdoruesin <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen. Kjo ndikon te të gjithë përdoruesit e kësaj pajisjeje, duke përfshirë ata me profile të punës."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Çinstalimet në ekzekutim"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Çinstalimet e dështuara"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Po e çinstalon…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> po çinstalohet…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Çinstalimi përfundoi."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> u çinstalua"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Çinstalimi nuk pati sukses."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Çinstalimi i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nuk u krye me sukses."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nuk mund të çinstalohet aplikacioni aktiv i administratorit të pajisjes"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nuk mund të çinstalohet aplikacioni aktiv i administratorit të pajisjes për <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ky aplikacion kërkohet për disa përdorues ose profile dhe është çinstaluar për të tjerët"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ky aplikacion nevojitet për profilin tënd dhe nuk mund të çinstalohet."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ky aplikacion kërkohet nga administratori i pajisjes dhe nuk mund të çinstalohet."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Menaxho aplikacionet e administratorit të pajisjes"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Menaxho përdoruesit"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mundi të çinstalohej."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kishte një problem me analizimin e paketës."</string>
+ <string name="newPerms" msgid="6039428254474104210">"E re"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Të gjitha"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privatësia"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Qasja në pajisje"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Ky përditësim nuk kërkon leje të reja."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuzo"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Informacione të tjera"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Refuzo sidoqoftë"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> nga <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Të lejohet <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> që të <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Të lejohet gjithmonë <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> që <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Vetëm gjatë përdorimit të aplikacionit"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Gjithmonë"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Refuzo dhe mos pyet përsëri"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> të çaktivizuara"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"të gjitha të çaktivizuara"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"asnjë e çaktivizuar"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Lejo"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacionet"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Lejet e aplikacionit"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Mos pyet përsëri"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Nuk ka leje"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Lejet shtesë"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Hap informacionet e aplikacionit"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të tjera</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> të tjera</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ky aplikacion është projektuar për një version më të vjetër të Android. Refuzimi i lejeve mund të shkaktojë që ai të mos funksionojë më siç duhet."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"kryej një veprim të panjohur"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> aplikacione nga <xliff:g id="COUNT_1">%2$d</xliff:g> të tilla u lejuan"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Shfaq sistemin"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Fshih sistemin"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Asnjë aplikacion"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Cilësimet e vendndodhjeve"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> është një ofrues i shërbimeve të vendndodhjes për këtë pajisje. Qasja e vendndodhjes mund të modifikohet nga cilësimet e vendndodhjes."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Nëse e refuzon këtë leje, funksionet bazë të pajisjes tënde mund të mos funksionojnë më siç pritet."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Zbatuar nga politika"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Qasja në sfond është e çaktivizuar sipas politikës"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Qasja në sfond është e aktivizuar sipas politikës"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Qasja në planin e parë është e aktivizuar sipas politikës"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolluar nga administratori"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Gjithmonë"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Vetëm gjatë përdorimit të aplikacionit"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Asnjëherë"</string>
+ <string name="loading" msgid="7811651799620593731">"Po ngarkon..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Të gjitha lejet"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Kapacitete të tjera të aplikacionit"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Kërkesa e lejes"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Mbivendosja e ekranit u zbulua"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Për të ndryshuar këtë cilësim të lejes, në fillim duhet të çaktivizosh mbivendosjen e ekranit nga Cilësimet > Aplikacionet"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Hap cilësimet"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Teknologjia \"Android\" që vishet"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instalo/çinstalo veprimet që nuk mbështeten në teknologjinë që vishet."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Zgjidh se ku do të lejohet të ketë qasje <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> është përditësuar. Zgjidh se ku do të lejohet të ketë qasje ky aplikacion."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Anulo"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Vazhdo"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Lejet e reja"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Lejet aktuale"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Po vihet në përdorim aplikacioni..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"E panjohur"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Për sigurinë tënde, tableti yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Për sigurinë tënde, televizori yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Për sigurinë tënde, telefoni yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefoni dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj telefonit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tableti dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj tabletit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Televizori dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj televizorit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Vazhdo"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Cilësimet"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Instalimi/çinstalimi i aplikacioneve të \"Wear\""</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sr-television/strings.xml b/packages/PackageInstaller/res/values-sr-television/strings.xml
new file mode 100644
index 0000000..fcfe156
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sr-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Одбиј и не питај поново"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Ово можете да промените касније у Подешавањима > Апликације"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Прикажи системске апликације"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Дозволе за апликације"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Дозволе за апликације"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Дозволе за апликацију <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Додатне дозволе"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Дозволе за апликацију <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sr-watch/strings.xml b/packages/PackageInstaller/res/values-sr-watch/strings.xml
new file mode 100644
index 0000000..7e15b01
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sr-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Одбиј и не питај поново"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Прикажи системске апликације"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Не може да се промени"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Да"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Откажи"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml
new file mode 100644
index 0000000..494b0d4
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sr/strings.xml
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Упаковани програм за инсталацију"</string>
+ <string name="next" msgid="3057143178373252333">"Даље"</string>
+ <string name="install" msgid="5896438203900042068">"Инсталирај"</string>
+ <string name="done" msgid="3889387558374211719">"Готово"</string>
+ <string name="cancel" msgid="8360346460165114585">"Откажи"</string>
+ <string name="installing" msgid="8613631001631998372">"Инсталирање..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Инсталира се <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Апликација је инсталирана."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Желите ли да инсталирате ову апликацију? Имаће приступ следећем:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Желите ли да инсталирате ову апликацију? Не захтева посебан приступ."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Желите ли да инсталирате ажурирање за ову постојећу апликацију? Постојећи подаци неће бити изгубљени. Ажурирана апликација имаће приступ следећем:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Желите ли да инсталирате ажурирање за ову уграђену апликацију? Постојећи подаци неће бити изгубљени. Ажурирана апликација ће имати приступ следећем:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Да ли желите да инсталирате ажурирање ове постојеће апликације? Постојећи подаци неће бити изгубљени. Није потребан посебан приступ."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Да ли желите да инсталирате ажурирање ове уграђене апликације? Постојећи подаци неће бити изгубљени. Није потребан посебан приступ."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Апликација није инсталирана."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Инсталирање пакета је блокирано."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Апликација није инсталирана јер је пакет неусаглашен са постојећим пакетом."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Апликација није инсталирана јер није компатибилна са таблетом."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ова апликација није компатибилна са ТВ-ом."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Апликација није инсталирана јер није компатибилна са телефоном."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Апликација није инсталирана јер је пакет неважећи."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Није могуће инсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на таблет."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Нисмо успели да инсталирамо <xliff:g id="APP_NAME">%1$s</xliff:g> на ТВ."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Није могуће инсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на телефон."</string>
+ <string name="launch" msgid="4826921505917605463">"Отвори"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Администратор не дозвољава инсталирање апликација добијених из непознатих извора"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Овај корисник не може да инсталира непознате апликације"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Овом кориснику није дозвољено да инсталира апликације"</string>
+ <string name="ok" msgid="3468756155452870475">"Потврди"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Управљање апликацијама"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Нема више места"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Није могуће инсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>. Ослободите додатни простор и покушајте поново."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Апликација није пронађена"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Апликација није пронађена на листи инсталираних апликација."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Није дозвољено"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Актуелном кориснику није дозвољено да обави ово деинсталирање."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Грешка"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Деинсталирање апликације није успело."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Деинсталирање апликације"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Деинсталирање ажурирања"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> је део следеће апликације:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Да ли желите да деинсталирате ову апликацију?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Да ли желите да деинсталирате ову апликацију за "<b>"све"</b>" кориснике? Апликација и подаци који се на њу односе биће уклоњени за "<b>"све"</b>" кориснике овог уређаја."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Желите ли да деинсталирате ову апликацију за корисника <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени. Ово утиче на све кориснике овог уређаја, укључујући и оне са профилима за Work."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активна деинсталирања"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Неуспела деинсталирања"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Деинсталирање..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Деинсталирање је завршено."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Апликација <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> је деинсталирана"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Деинсталирање није успело."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Деинсталирање апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> није успело."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Не можете да деинсталирате апликацију за активног администратора уређаја"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Не можете да деинсталирате апликацију за активног администратора уређаја за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ова апликација је потребна за неке кориснике или профиле, а деинсталирана је за друге"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ова апликација је потребна за ваш профил и не може да се деинсталира."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ова апликација је потребна администратору уређаја и не може да се деинсталира."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Управљај апликацијама за администраторе уређаја"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Управљаj корисницима"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Није могуће деинсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Дошло је до проблема при рашчлањивању пакета."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Ново"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Све"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Приватност"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Приступ уређају"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Ово ажурирање не захтева нове дозволе."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Одбаци"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Више информација"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Ипак одбиј"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. од <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Желите ли да дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Желите ли увек да дозволите да <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Само док се апликација користи"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Увек"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Одбиј и не питај поново"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Онемогућених: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"све су онемогућене"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ниједна није онемогућена"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Дозволи"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Апликације"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Дозволе за апликације"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Не питај поново"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Нема дозвола"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Додатне дозволе"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Отвори информације о апликацији"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">још <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">још <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">још <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ова апликација је дизајнирана за старију верзију Android-а. Ако одбијете дозволу, она можда више неће правилно да функционише."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"обавља непознату радњу"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> од <xliff:g id="COUNT_1">%2$d</xliff:g> апликација има дозволу"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Прикажи системске"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Сакриј системске"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Нема апликација"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Подешавања локације"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> пружа услуге локације за овај уређај. Приступ локацији можете да измените у подешавањима локације."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Ако одбијете ову дозволу, основне функције уређаја можда неће више функционисати исправно."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Примењује се у складу са смерницама"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Приступ у позадини је онемогућен смерницама"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Приступ у позадини је омогућен смерницама"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Приступ у првом плану је омогућен смерницама"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролише администратор"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Увек"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Само док се апликација користи"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Никада"</string>
+ <string name="loading" msgid="7811651799620593731">"Учитава се…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Све дозволе"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Остале могућности апликације"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Захтев за дозволу"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Откривен је елемент који прекрива садржај екрана"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Да бисте променили подешавање ове дозволе, прво треба да искључите елемент који прекрива садржај екрана у одељку Подешавања > Апликације"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Отвори подешавања"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Радње Инсталирај/Деинсталирај нису подржане у Wear-у."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Изаберите чему <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> може да приступа"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Апликација <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> је ажурирана. Изаберите чему ова апликација може да приступа."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Откажи"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Настави"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Нове дозволе"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Актуелне дозволе"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Апликација се припрема…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Непознато"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Таблету из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Телевизору из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Телефону из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефон и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења телефона или губитак података до којих може да дође због њеног коришћења."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таблет и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења таблета или губитак података до којих може да дође због њеног коришћења."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ТВ и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења ТВ-а или губитак података до којих може да дође због њеног коришћења."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Настави"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Подешавања"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Инсталирање/деинсталирање Wear апликација"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sv-television/strings.xml b/packages/PackageInstaller/res/values-sv-television/strings.xml
new file mode 100644
index 0000000..5f23767
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sv-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Neka och fråga inte igen"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Du kan ändra detta senare i Inställningar > Appar"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Visa systemappar"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Appens behörigheter"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Appens behörigheter"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Behörigheter för <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Ytterligare behörigheter"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Behörigheter för <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sv-watch/strings.xml b/packages/PackageInstaller/res/values-sv-watch/strings.xml
new file mode 100644
index 0000000..f20ec21
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sv-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Avvisa och fråga inte igen"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Visa systemappar"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Kan inte ändras"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ja"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Avbryt"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
new file mode 100644
index 0000000..ff4f4c1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Installationsprogram för paket"</string>
+ <string name="next" msgid="3057143178373252333">"Nästa"</string>
+ <string name="install" msgid="5896438203900042068">"Installera"</string>
+ <string name="done" msgid="3889387558374211719">"Färdig"</string>
+ <string name="cancel" msgid="8360346460165114585">"Avbryt"</string>
+ <string name="installing" msgid="8613631001631998372">"Installerar…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeras …"</string>
+ <string name="install_done" msgid="3682715442154357097">"Appen har installerats."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Vill du installera den här appen? Den får åtkomst till:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vill du installera den här appen? Den kräver ingen särskild åtkomst."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Vill du installera en uppdatering till den här befintliga appen? Dina befintliga data försvinner inte. Den uppdaterade appen får åtkomst till:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vill du installera en uppdatering till den här befintliga förinstallerade appen? Dina befintliga data försvinner inte. Den uppdaterade appen får åtkomst till:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vill du installera en uppdatering av den befintliga appen? Dina befintliga data försvinner inte. Ingen särskild åtkomst krävs."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vill du installera en uppdatering av den inbyggda appen? Dina befintliga data försvinner inte. Ingen särskild åtkomst krävs."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Appen har inte installerats."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paketet har blockerats för installation."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Appen har inte installerats på grund av en konflikt mellan detta paket och ett befintligt paket."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Appen har inte installerats eftersom den inte är kompatibel med surfplattan."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Appen är inte kompatibel med din TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Appen har inte installerats eftersom den inte är kompatibel med mobilen."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Appen har inte installerats eftersom paketet verkar vara ogiltigt."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g> på surfplattan."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunde inte installeras på TV:n."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g> på mobilen."</string>
+ <string name="launch" msgid="4826921505917605463">"Öppna"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratören tillåter inte installation av appar från okända källor"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Denna användare får inte installera okända appar"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Användaren har inte behörighet att installera appar"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Hantera appar"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Slut på utrymme"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g>. Frigör minne och försök igen."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Appen hittades inte"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Appen fanns inte i listan över installerade appar."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ingen behörighet"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Den aktuella användaren har inte behörighet att utföra avinstallationen."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fel"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Det gick inte att installera appen."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Avinstallera appen"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Avinstallera uppdateringen"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> är en del av följande app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Vill du avinstallera appen?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vill du avinstallera den här appen för "<b>"alla"</b>" användare? Appen och alla data i den tas bort från "<b>"alla"</b>" användare på enheten."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vill du avinstallera appen för användaren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort. Detta påverkar alla som använder enheten, även dem med jobbprofiler."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Avinstallationer som pågår"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Avinstallationer som misslyckats"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Avinstallerar…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> avinstalleras …"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Avinstallationen har slutförts."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> har avinstallerats"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Det gick inte att avinstallera."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Det gick inte att avinstallera <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Det går inte att avinstallera den aktiva appen för enhetsadministratör"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Det går inte att avinstallera den aktiva appen för enhetsadministratör för <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Den här appen är obligatorisk för vissa användare och profiler och har avinstallerats för andra"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Appen behövs i profilen och det går inte att avinstallera den"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Appen krävs av enhetsadministratören och kan därför inte avinstalleras."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Hantera appar för enhetsadministratör"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Hantera användare"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Det gick inte att avinstallera <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ett problem uppstod när paketet analyserades."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Nytt"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Alla"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Sekretess"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Enhetsåtkomst"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Det krävs inga nya behörigheter för den här uppdateringen."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Neka"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mer information"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Neka ändå"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> av <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Tillåter du <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> att <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vill du alltid tillåta att <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Bara när appen används"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Alltid"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Neka och fråga inte igen"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> har inaktiverats"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"alla har inaktiverats"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"inga har inaktiverats"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Tillåt"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Appar"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Appens behörigheter"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Fråga inte igen"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Inga behörigheter"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Ytterligare behörigheter"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Öppna appinformation"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> till</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> till</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Den här appen utformades för en äldre version av Android. Om du nekar appen behörighet kan det hända att den inte längre fungerar som den ska."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"utför en okänd åtgärd"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> av <xliff:g id="COUNT_1">%2$d</xliff:g> appar tillåts"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Visa systemet"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Dölj systemet"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Inga appar"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Platsinställningar"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> är en platstjänstleverantör för enheten. Platsåtkomsten kan redigeras i platsinställningarna."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Om du nekar appen behörighet kan det hända att grundläggande funktioner på enheten inte fungerar som de ska."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enligt policyn"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Åtkomst i bakgrunden har inaktiverats av en princip"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Åtkomst i bakgrunden har aktiverats av en princip"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Åtkomst i förgrunden har aktiverats av en princip"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Styrs av administratören"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Alltid"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Bara när appen används"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Aldrig"</string>
+ <string name="loading" msgid="7811651799620593731">"Läser in …"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Alla behörigheter"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Andra appbehörigheter"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Begäran om behörighet"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Skärmöverlagring har upptäckts"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Innan du kan ändra den här behörighetsinställningen måste du inaktivera skärmöverlagring under Inställningar > Appar"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Öppna inställningarna"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Åtgärder för att installera/avinstallera stöds inte på Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Välj vad du vill ge <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> åtkomst till"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> har uppdaterats. Välj vad du vill ge appen åtkomst till."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Avbryt"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Fortsätt"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Nya behörigheter"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Nuvarande behörighet"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Provkör appen …"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Okänd"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Av säkerhetsskäl får okända appar från den här källan inte installeras av surfplattan."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Av säkerhetsskäl får okända appar från den här källan inte installeras av TV:n."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Av säkerhetsskäl får okända appar från den här källan inte installeras av mobilen."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Din mobil och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på mobilen och för dataförlust som kan uppstå vid användning av denna app."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Din surfplatta och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på surfplattan och för dataförlust som kan uppstå vid användning av denna app."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Din TV och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på TV:n och för dataförlust som kan uppstå vid användning av denna app."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Fortsätt"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Inställningar"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear-appar installeras/avinstalleras"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sw-television/strings.xml b/packages/PackageInstaller/res/values-sw-television/strings.xml
new file mode 100644
index 0000000..25fd696
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sw-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Hapana na usiulize tena"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Unaweza kubadilisha hatua hii baadaye kwenye Mipangilio na Programu"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Onyesha programu za mfumo"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Ruhusa za programu"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Ruhusa za programu"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Ruhusa za <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Ruhusa za ziada"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Ruhusa za <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sw-watch/strings.xml b/packages/PackageInstaller/res/values-sw-watch/strings.xml
new file mode 100644
index 0000000..30d68e5
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sw-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Hapana, usiulize tena"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Onyesha programu za mfumo"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Haiwezi kubadilishwa"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ndiyo"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Ghairi"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml
new file mode 100644
index 0000000..c431983
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sw/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Kisakinishaji cha furushi"</string>
+ <string name="next" msgid="3057143178373252333">"Inayofuata"</string>
+ <string name="install" msgid="5896438203900042068">"Sakinisha"</string>
+ <string name="done" msgid="3889387558374211719">"Nimemaliza"</string>
+ <string name="cancel" msgid="8360346460165114585">"Ghairi"</string>
+ <string name="installing" msgid="8613631001631998372">"inawekwa..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Inasakinisha <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Programu imewekwa."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Je, ungependa kuiweka programu hii? Itaweza:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Je, ungependa kuiweka programu hii? Haihitaji idhini ya kufikia kitu chochote."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Je, unataka kuweka sasisho katika programu hii? Data yako iliyopo haitapotea. Programu iliyosasishwa itaweza:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Je, unataka kuweka sasisho la programu hii iliyojengewa ndani? Data yako iliyopo haitapotea. Programu iliyosasishwa itaweza:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Je, unataka kuweka sasisho la programu hii? Data yako iliyopo haitapotea. Haihitaji idhini yoyote maalum ya kufikia."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Je, unataka kuweka sasisho la programu hii? Data yako iliyopo haitapotea. Haihitaji idhini yoyote maalum ya kufikia."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Programu haikusakinishwa."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Kifurushi kimezuiwa kisisakinishwe."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Programu haikusakinishwa kwa sababu haiafikiani na kifurushi kingine kilichopo."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Programu haikusakinishwa kwa sababu haioani na kompyuta kibao yako."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Programu hii haioani na runinga yako."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Programu haikusakinishwa kwa sababu haioani na simu yako."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Programu haikusakinishwa kwa sababu inaonekana kuwa kifurushi si sahihi."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> haikuweza kusakinishwa kwenye kompyuta yako kibao."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> haikuweza kusakinishwa kwenye runinga yako."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> haikuweza kusakinishwa kwenye simu yako."</string>
+ <string name="launch" msgid="4826921505917605463">"Fungua"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Msimamizi wako haruhusu usakinishaji wa programu zinazopatikana kutoka vyanzo visivyojulikana"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Mtumiaji huyu hana idhini ya kusakinisha programu ambazo hazijulikani"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Mtumiaji huyu haruhusiwi kusakinisha programu"</string>
+ <string name="ok" msgid="3468756155452870475">"Sawa"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Dhibiti programu"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nafasi imeisha"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> haingeweza kusakinishwa. Wezesha nafasi kiasi na ujaribu tena."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Programu haikupatikana"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Programu haikupatikana katika orodha ya programu zilizosakinishwa."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Hairuhusiwi"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Mtumiaji wa sasa hana ruhusa ya kuondoa kipengee hiki."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Hitilafu"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Imeshindwa kuondoa programu."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Sanidua programu"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Sanidua kisasisho"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ni sehemu ya programu ifuatayo:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Unataka kusanidua programu hii?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Je, unataka kusanidua programu hii kwa "<b>"watumiaji"</b>" wote? Programu na data yake zitaondolewa kutoka kwa "<b>"watumiaji"</b>" kwenye kifaa."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Je, unataka kuondoa programu hii kwa mtumiaji <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Ungependa kubadilisha programu hii na toleo la kiwanda? Data yote itaondolewa."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Ungependa kubadilisha programu hii na toleo la kiwanda? Data yote itaondolewa. Hatua hii itaathiri watumiaji wote wa kifaa hiki, ikiwa ni pamoja na wale walio na wasifu za kazini."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Mara ambazo programu inaondolewa sasa"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mara ambazo programu haikuondolewa"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Inasanidua..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Inaondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Imesaniduliwa."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Imeondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Kusanidua hakukufaulu."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Imeshindwa kuondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Imeshindwa kuondoa programu inayotumika ya msimamizi wa kifaa"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Imeshindwa kuondoa programu inayotumika ya msimamizi wa kifaa cha <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Baadhi ya wasifu au watumiaji wanahitaji programu, kwa hivyo haijaondolewa kwa wengine"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Programu hii inahitajika kwa wasifu wako kwa hivyo haiwezi kuondolewa."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Programu hii inahitajika na msimamizi wako wa kifaa na haiwezi kuondolewa."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Dhibiti programu za msimamizi wa kifaa"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Dhibiti watumiaji"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> haingeweza kusaniduliwa."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kulikuwa na tatizo la kuchanganua furushi."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Mpya"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Zote"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Faragha"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Kufikia Kifaa"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Sasisho hili halihitaji vibali vipya."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Hapana"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Maelezo zaidi"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Kataa"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> kati ya <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Ungependa kuruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Ungependa kuruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> itekeleze <xliff:g id="ACTION">%2$s</xliff:g> kila wakati?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Wakati unatumia programu tu"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Kila wakati"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Kataa na usiulize tena"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> zimezimwa"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"zimezimwa zote"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"hakuna zilizozimwa"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Ndiyo"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Programu"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Ruhusa za programu"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Usiulize tena"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Hakuna ruhusa"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Ruhusa za ziada"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Fungua maelezo ya programu"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> zaidi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> zaidi</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Programu hii iliundwa kwa ajili ya toleo la zamani la Android. Kuinyima ruhusa kunaweza kusababisha iache kutenda kazi kama ilivyokusudiwa."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"kutekeleza kitendo kisichojulikana"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Inaruhusu programu <xliff:g id="COUNT_0">%1$d</xliff:g> kati ya <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Onyesha mfumo"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ficha mfumo"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Hakuna programu"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Mipangilio ya Mahali"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> hutoa huduma za mahali kwenye kifaa hiki. Idhini ya kufikia mahali inaweza kurekebishwa katika mipangilio ya mahali."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Usipokubali ruhusa hii, huenda vipengele vya msingi vya kifaa chako havitafanya kazi kama ilivyokusudiwa."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Hutekelezwa na sera"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Ufikiaji wa chinichini umezimwa na sera"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Ufikiaji wa chinichini umewashwa na sera"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ufikiaji wa hadharani umewashwa na sera"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Imedhibitiwa na msimamizi"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Kila wakati"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Wakati unatumia programu tu"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Kamwe"</string>
+ <string name="loading" msgid="7811651799620593731">"Inapakia…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Ruhusa zote"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Uwezo mwingine wa programu"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Ombi la idhini"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Imetambua tangazo lililowekelewa juu ya skrini"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Ili kubadilisha mpangilio huu wa ruhusa, ni lazima kwanza uzime tangazo lililowekelewa juu ya skrini kwenye Mipangilio na Programu"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Fungua mipangilio"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Huduma ya Android Wear haiwezi kutekeleza vitendo vya Kusakinisha au Kuondoa vipengee."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Chagua vipengee ambavyo unaruhusu <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifikie"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> imesasishwa. Chagua vipengee unavyoruhusu programu hii ifikie."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Ghairi"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Endelea"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Ruhusa mpya"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Ruhusa zilizopo"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Inatayarisha programu..."</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Isiyojulikana"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Kwa sababu ya usalama wako, kompyuta yako kibao haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Kwa sababu ya usalama wako, TV yako haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Kwa sababu ya usalama wako, simu yako haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Data yako ya binafsi na ya simu yako inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibika kutokana na uharibifu wowote kwenye simu yako au kupotea kwa data kutokana na matumizi yake."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Data yako ya binafsi na ya kompyuta yako kibao inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibika kutokana na uharibifu wowote kwenye kompyuta yako kibao au kupotea kwa data kutokana na matumizi yake."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Data yako ya binafsi na ya televisheni yako inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibika kutokana na uharibifu wowote kwenye televisheni yako au kupotea kwa data kutokana na matumizi yake."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Endelea"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Mipangilio"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Inasakinisha/inaondoa programu za Android Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sw180dp-notround-watch/dimens.xml b/packages/PackageInstaller/res/values-sw180dp-notround-watch/dimens.xml
new file mode 100644
index 0000000..84072a2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sw180dp-notround-watch/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Dimens for dialog layouts -->
+ <dimen name="diag_button_size">48dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-sw210dp-round-watch/dimens.xml b/packages/PackageInstaller/res/values-sw210dp-round-watch/dimens.xml
new file mode 100644
index 0000000..d896138
--- /dev/null
+++ b/packages/PackageInstaller/res/values-sw210dp-round-watch/dimens.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <!-- Dimens for dialog layouts -->
+ <dimen name="diag_button_size">54dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ta-television/strings.xml b/packages/PackageInstaller/res/values-ta-television/strings.xml
new file mode 100644
index 0000000..786bbe2
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ta-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"நிராகரி, மீண்டும் கேட்காதே"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"அமைப்புகள் > பயன்பாடுகள் என்பதில் பிறகு மாற்றலாம்"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"முறைமைப் பயன்பாடுகளைக் காட்டு"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"பயன்பாட்டு அனுமதிகள்"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"பயன்பாட்டு அனுமதிகள்"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> அனுமதிகள்"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"கூடுதல் அனுமதிகள்"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> அனுமதிகள்"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ta-watch/strings.xml b/packages/PackageInstaller/res/values-ta-watch/strings.xml
new file mode 100644
index 0000000..23dab29
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ta-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"நிராகரி, மீண்டும் கேட்காதே"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"முறைமைப் பயன்பாடுகளைக் காட்டு"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"மாற்ற முடியாது"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ஆம்"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"ரத்துசெய்"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml
new file mode 100644
index 0000000..366f6d9
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ta/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"பேக்கேஜ் இன்ஸ்டாலர்"</string>
+ <string name="next" msgid="3057143178373252333">"அடுத்து"</string>
+ <string name="install" msgid="5896438203900042068">"நிறுவு"</string>
+ <string name="done" msgid="3889387558374211719">"முடிந்தது"</string>
+ <string name="cancel" msgid="8360346460165114585">"ரத்துசெய்"</string>
+ <string name="installing" msgid="8613631001631998372">"நிறுவுகிறது…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவுகிறது…"</string>
+ <string name="install_done" msgid="3682715442154357097">"பயன்பாடு நிறுவப்பட்டது."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"இந்தப் பயன்பாட்டை நிறுவ விரும்புகிறீர்களா? அது இதற்கான அணுகலைப் பெறும்:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"இந்தப் பயன்பாட்டை நிறுவ விரும்புகிறீர்களா? இதற்கு எந்தத் தனிப்பட்ட அணுகலும் தேவையில்லை."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"முன்பே உள்ள இந்தப் பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்க மாட்டீர்கள். புதுப்பிக்கப்பட்ட பயன்பாடு இதற்கான அணுகலைப் பெறும்:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"உள்ளமைக்கப்பட்ட பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்க மாட்டீர்கள். புதுப்பிக்கப்பட்ட பயன்பாடு இதற்கான அணுகலைப் பெறும்:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"முன்பே உள்ள இந்தப் பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்கமாட்டீர்கள். இதற்குத் தனிப்பட்ட அணுகல் எதுவும் தேவையில்லை."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"உள்ளமைக்கப்பட்ட பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்க மாட்டீர்கள். இதற்குத் தனிப்பட்ட அணுகல் எதுவும் தேவையில்லை."</string>
+ <string name="install_failed" msgid="6579998651498970899">"பயன்பாடு நிறுவப்படவில்லை."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"இந்தத் தொகுப்பு நிறுவுவதிலிருந்து தடுக்கப்பட்டது."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"தொகுப்பானது தற்போதுள்ள தொகுப்புடன் இணக்கமற்றதாக உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"உங்கள் டேப்லெட்டுடன் இணக்கமற்றதாக உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"உங்கள் டிவியுடன் இந்தப் பயன்பாடு இணங்கவில்லை."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"உங்கள் மொபைலுடன் இணக்கமற்றதாக உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"தொகுப்பு தவறானது போல் உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை உங்கள் டேப்லெட்டில் நிறுவ முடியாது."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"உங்கள் டிவியில் <xliff:g id="APP_NAME">%1$s</xliff:g>ஐ நிறுவ முடியவில்லை."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை உங்கள் மொபைலில் நிறுவ முடியாது."</string>
+ <string name="launch" msgid="4826921505917605463">"திற"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"அறியப்படாத மூலங்களிலிருந்து பெற்ற பயன்பாடுகளை நிறுவ, உங்கள் நிர்வாகி அனுமதிக்கவில்லை"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"அறியப்படாத பயன்பாடுகளை, இந்தப் பயனர் நிறுவ முடியாது"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"பயன்பாடுகளை நிறுவ, இந்தப் பயனருக்கு அனுமதியில்லை"</string>
+ <string name="ok" msgid="3468756155452870475">"சரி"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"பயன்பாடுகளை நிர்வகிக்கவும்"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"இடம் இல்லை"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை நிறுவ முடியாது. சில இடத்தைக் காலி செய்து மீண்டும் முயற்சிக்கவும்."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"பயன்பாடு கண்டறியப்படவில்லை"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"நிறுவிய பயன்பாடுகளின் பட்டியலில் பயன்பாடு இல்லை."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"அனுமதிக்கப்படவில்லை"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"இதை நிறுவல் நீக்குவதற்கு, தற்போதைய பயனர் அனுமதிக்கப்படவில்லை."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"பிழை"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"பயன்பாட்டை நிறுவல் நீக்க முடியவில்லை."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"பயன்பாட்டை நிறுவல் நீக்கு"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"புதுப்பிப்பை நிறுவல் நீக்கு"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ஆனது பின்வரும் பயன்பாட்டின் பகுதியாகும்:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"இந்தப் பயன்பாட்டை நிறுவல் நீக்க விரும்புகிறீர்களா?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"இந்தப் பயன்பாட்டை "<b>"எல்லா"</b>" பயனர்களுக்கும் நிறுவல் நீக்க விரும்புகிறீர்களா? பயன்பாடும், அதன் தரவும் சாதனத்தில் உள்ள "<b>"எல்லா"</b>" பயனர்களிடமிருந்தும் அகற்றப்படும்."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> பயனருக்கான இந்தப் பயன்பாட்டை நிறுவல்நீக்க விரும்புகிறீர்களா?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ஆரம்பநிலைப் பதிப்பாக இந்தப் பயன்பாட்டை மாற்றியமைக்கவா? எல்லா தரவும் அகற்றப்படும்."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ஆரம்பநிலைப் பதிப்பாக இந்தப் பயன்பாட்டை மாற்றியமைக்கவா? எல்லா தரவும் அகற்றப்படும். பணிச் சுயவிவரங்களுடன் உள்ளவர்கள் உட்பட இந்தச் சாதனத்தின் எல்லா பயனர்களையும் இது பாதிக்கும்."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"இயக்கத்திலுள்ள நிறுவல் நீக்கங்கள்"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"தோல்வியடைந்த நிறுவல் நீக்கங்கள்"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"நிறுவலை நீக்குகிறது…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்குகிறது…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"நிறுவல் நீக்குவது முடிந்தது."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> நிறுவல் நீக்கப்பட்டது"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"நிறுவல் நீக்குவதில் தோல்வி."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்க முடியவில்லை."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"செயலில் உள்ள சாதன நிர்வாகிப் பயன்பாட்டை நிறுவல் நீக்க முடியாது"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>க்கான செயலில் உள்ள சாதன நிர்வாகிப் பயன்பாட்டை நிறுவல் நீக்க முடியாது"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"இது சில பயனர்கள்/சுயவிவரங்களுக்குத் தேவைப்படுவதால், நிறுவல்நீக்க முடியாது, பிறருக்கு நிறுவல் நீக்கப்பட்டது"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"உங்கள் சுயவிவரத்திற்கு இந்தப் பயன்பாடு தேவைப்படுவதால், அதை நிறுவல்நீக்க முடியாது, பிறருக்கு நிறுவல் நீக்கப்பட்டது."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"சாதன நிர்வாகிக்கு இந்தப் பயன்பாடு தேவைப்படுவதால், நிறுவல்நீக்க முடியாது."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"சாதன நிர்வாகிப் பயன்பாடுகளை நிர்வகி"</string>
+ <string name="manage_users" msgid="3125018886835668847">"பயனர்களை நிர்வகி"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை நிறுவல் நீக்க முடியாது."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"தொகுப்பைக் குறியீட்டு ஆய்வு செய்வதில் சிக்கல் ஏற்பட்டது."</string>
+ <string name="newPerms" msgid="6039428254474104210">"புதிது"</string>
+ <string name="allPerms" msgid="1024385515840703981">"எல்லாம்"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"தனியுரிமை"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"சாதன அணுகல்"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"இந்தப் புதுப்பிப்பிற்குப் புதிய அனுமதிகள் எதுவும் தேவையில்லை."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"நிராகரி"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"மேலும் தகவல்"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"பரவாயில்லை, நிராகரி"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"செயலைச் செய்ய <xliff:g id="ACTION">%2$s</xliff:g>, <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ஐ அனுமதிக்கவா?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<xliff:g id="ACTION">%2$s</xliff:g>ஐச் செய்ய <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ஆப்ஸை எப்போதும் அனுமதிக்கவா?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ஆப்ஸைப் பயன்படுத்தும்போது மட்டும் அனுமதி"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"எப்போதும் அனுமதி"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"நிராகரி, மீண்டும் கேட்காதே"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> முடக்கப்பட்டன"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"எல்லாம் முடக்கப்பட்டன"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"எதுவும் முடக்கப்படவில்லை"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"அனுமதி"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ஆப்ஸ்"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"பயன்பாட்டு அனுமதிகள்"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"மீண்டும் கேட்காதே"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"அனுமதிகள் இல்லை"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"கூடுதல் அனுமதிகள்"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"பயன்பாட்டுத் தகவலைத் திற"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">மேலும் <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">மேலும் <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"இந்தப் பயன்பாடு Android இன் பழைய பதிப்புக்காக வடிவமைக்கப்பட்டது. அனுமதியை மறுத்தால் அது சரியாக செயல்படாமல் போகலாம்."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"அறியாத செயலைச் செயல்படுத்தும்"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"அனுமதிக்கப்பட்ட ஆப்ஸ்: <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"எல்லாம் காட்டு"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"முறைமையை மறை"</string>
+ <string name="no_apps" msgid="1965493419005012569">"பயன்பாடுகள் இல்லை"</string>
+ <string name="location_settings" msgid="1774875730854491297">"இருப்பிட அமைப்புகள்"</string>
+ <string name="location_warning" msgid="8778701356292735971">"இந்தச் சாதனத்திற்கான இருப்பிடச் சேவைகளின் வழங்குநர் <xliff:g id="APP_NAME">%1$s</xliff:g> ஆகும். இருப்பிட அமைப்புகளிலிருந்து இருப்பிட அணுகலை மாற்றலாம்."</string>
+ <string name="system_warning" msgid="7103819124542305179">"இந்த அனுமதியை நிராகரித்தால், உங்கள் சாதனத்தின் அடிப்படை அம்சங்கள் சரியாகச் செயல்படாமல் போகலாம்."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"கொள்கையின் படி செயல்படுத்தப்பட்டது"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"கொள்கையின்படி பின்புல அணுகல் முடக்கப்பட்டது"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"கொள்கையின்படி பின்புல அணுகல் இயக்கப்பட்டது"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"கொள்கையின்படி முன்புல அணுகல் இயக்கப்பட்டது"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"எப்போதும்"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ஆப்ஸை உபயோகிக்கும்போது மட்டும்"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ஒருபோதும் வேண்டாம்"</string>
+ <string name="loading" msgid="7811651799620593731">"ஏற்றுகிறது..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"எல்லா அனுமதிகளும்"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"பயன்பாட்டின் பிற திறன்கள்"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"அனுமதி கோரிக்கை"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"திரையின் மேலே செயல்படும் பயன்பாடுகள் கண்டறியப்பட்டன"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"இந்த அனுமதியை மாற்ற, அமைப்புகள் > பயன்பாடுகள் என்பதற்குச் சென்று, திரையின் மேலே செயல்படும் பயன்பாடுகளை முதலில் முடக்கவும்"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"அமைப்புகளைத் திற"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear இல் நிறுவுதல்/நிறுவல் நீக்குதலுக்கு ஆதரவில்லை."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> எவற்றை அணுகலாம் என்பதைத் தேர்வுசெய்யவும்"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> புதுப்பிக்கப்பட்டது. இந்தப் பயன்பாடு எவற்றை அணுகலாம் என்பதைத் தேர்வுசெய்யவும்."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"ரத்துசெய்"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"தொடர்க"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"புதிய அனுமதிகள்"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"தற்போதைய அனுமதிகள்"</string>
+ <string name="message_staging" msgid="6151794817691100003">"பயன்பாடு தயாராகிறது…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"தெரியாதது"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"உங்கள் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து அறியப்படாத பயன்பாடுகளை உங்கள் டேப்லெட்டில் நிறுவ முடியாது."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"உங்கள் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து அறியப்படாத பயன்பாடுகளை உங்கள் டிவியில் நிறுவ முடியாது."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"உங்கள் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து அறியப்படாத பயன்பாடுகளை உங்கள் மொபைலில் நிறுவ முடியாது."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"அறியப்படாத பயன்பாடுகள், உங்கள் மொபைலையும் தனிப்பட்ட தரவையும் அதிகம் பாதிக்கக்கூடும். இந்தப் பயன்பாட்டை நிறுவுவதால், அவற்றைப் பயன்படுத்தும் போது உங்கள் மொபைலுக்கு ஏதேனும் சேதம் ஏற்பட்டாலோ அல்லது தரவை இழந்தாலோ, அதற்கு நீங்கள்தான் பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"அறியப்படாத பயன்பாடுகள், உங்கள் டேப்லெட்டையும் தனிப்பட்ட தரவையும் அதிகம் பாதிக்கக்கூடும். இந்தப் பயன்பாட்டை நிறுவுவதால், அவற்றைப் பயன்படுத்தும் போது உங்கள் டேப்லெட்டுக்கு ஏதேனும் சேதம் ஏற்பட்டாலோ அல்லது தரவை இழந்தாலோ, அதற்கு நீங்கள்தான் பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"அறியப்படாத பயன்பாடுகள், உங்கள் டிவியையும் தனிப்பட்ட தரவையும் அதிகம் பாதிக்கக்கூடும். இந்தப் பயன்பாட்டை நிறுவுவதால், அவற்றைப் பயன்படுத்தும் போது உங்கள் டிவிக்கு ஏதேனும் சேதம் ஏற்பட்டாலோ அல்லது தரவை இழந்தாலோ, அதற்கு நீங்கள்தான் பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"தொடர்க"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"அமைப்புகள்"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"வியர் ஆப்ஸை நிறுவுதல்/நிறுவல் நீக்குதல்"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-te-television/strings.xml b/packages/PackageInstaller/res/values-te-television/strings.xml
new file mode 100644
index 0000000..51526b7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-te-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"నిరాకరిస్తున్నాను, మళ్లీ అడగవద్దు"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"మీరు దీన్ని తర్వాత సెట్టింగ్లు > అనువర్తనాల్లో మార్చవచ్చు"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"సిస్టమ్ అనువర్తనాలను చూపు"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"యాప్ అనుమతులు"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"యాప్ అనుమతులు"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> అనుమతులు"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"అదనపు అనుమతులు"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> అనుమతులు"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-te-watch/strings.xml b/packages/PackageInstaller/res/values-te-watch/strings.xml
new file mode 100644
index 0000000..d97e970
--- /dev/null
+++ b/packages/PackageInstaller/res/values-te-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"నిరాకరిస్తున్నాను,ఇక అడగవద్దు"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"సిస్టమ్ అనువర్తనాలను చూపు"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"మార్చడం సాధ్యపడదు"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"అవును"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"రద్దు చేయి"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
new file mode 100644
index 0000000..b612385
--- /dev/null
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"ప్యాకేజీ ఇన్స్టాలర్"</string>
+ <string name="next" msgid="3057143178373252333">"తర్వాత"</string>
+ <string name="install" msgid="5896438203900042068">"ఇన్స్టాల్ చేయండి"</string>
+ <string name="done" msgid="3889387558374211719">"పూర్తయింది"</string>
+ <string name="cancel" msgid="8360346460165114585">"రద్దు చేయి"</string>
+ <string name="installing" msgid="8613631001631998372">"ఇన్స్టాల్ చేస్తోంది…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని ఇన్స్టాల్ చేస్తోంది…"</string>
+ <string name="install_done" msgid="3682715442154357097">"యాప్ ఇన్స్టాల్ చేయబడింది."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"మీరు ఈ అనువర్తనాన్ని ఇన్స్టాల్ చేయాలనుకుంటున్నారా? ఇది వీటికి ప్రాప్యతను పొందుతుంది:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"మీరు ఈ యాప్ను ఇన్స్టాల్ చేయాలనుకుంటున్నారా? దీనికి ఎటువంటి ప్రత్యేక యాక్సెస్ అవసరం లేదు."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"మీరు ఈ ప్రస్తుత యాప్నకు అప్డేట్ను ఇన్స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. అప్డేట్ చేసిన యాప్ వీటికి యాక్సెస్ను పొందుతుంది:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"మీరు ఈ అంతర్నిర్మిత యాప్నకు అప్డేట్ను ఇన్స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. అప్డేట్ చేసిన యాప్ వీటికి యాక్సెస్ పొందుతుంది:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"మీరు ఈ ప్రస్తుత యాప్కు అప్డేట్ను ఇన్స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. దీనికి ఎటువంటి ప్రత్యేక యాక్సెస్ అవసరం లేదు."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"మీరు ఈ అంతర్నిర్మిత యాప్కు అప్డేట్ను ఇన్స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. దీనికి ఎటువంటి ప్రత్యేక యాక్సెస్ అవసరం లేదు."</string>
+ <string name="install_failed" msgid="6579998651498970899">"యాప్ ఇన్స్టాల్ చేయబడలేదు."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"ప్యాకేజీ ఇన్స్టాల్ కాకుండా బ్లాక్ చేయబడింది."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ప్యాకేజీ ఇప్పటికే ఉన్న ప్యాకేజీకి వైరుధ్యంగా ఉన్నందున యాప్ ఇన్స్టాల్ చేయబడలేదు."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"యాప్ మీ టాబ్లెట్కు అనుకూలంగా లేని కారణంగా ఇన్స్టాల్ చేయబడలేదు."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ఈ యాప్ మీ టీవీకి అనుకూలంగా లేదు."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"యాప్ మీ ఫోన్కు అనుకూలంగా లేని కారణంగా ఇన్స్టాల్ చేయబడలేదు."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ప్యాకేజీ చెల్లుబాటు కాని విధంగా ఉన్నందున యాప్ ఇన్స్టాల్ చేయబడలేదు."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను మీ టాబ్లెట్లో ఇన్స్టాల్ చేయడం సాధ్యపడలేదు."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని మీ టీవీలో ఇన్స్టాల్ చేయడం సాధ్యపడలేదు."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను మీ ఫోన్లో ఇన్స్టాల్ చేయడం సాధ్యపడలేదు."</string>
+ <string name="launch" msgid="4826921505917605463">"తెరవండి"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"మీ నిర్వాహకులు తెలియని మూలాల నుండి పొందిన అనువర్తనాల ఇన్స్టాలేషన్ను అనుమతించరు"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"తెలియని అనువర్తనాలను ఈ వినియోగదారు ఇన్స్టాల్ చేయలేరు"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"యాప్లను ఇన్స్టాల్ చేయడానికి ఈ వినియోగదారుకు అనుమతి లేదు"</string>
+ <string name="ok" msgid="3468756155452870475">"సరే"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"అనువర్తనాలను నిర్వహించండి"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ఖాళీ లేదు"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని ఇన్స్టాల్ చేయడం సాధ్యపడలేదు. కొంత స్థలాన్ని ఖాళీ చేసి మళ్లీ ప్రయత్నించండి."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"యాప్ కనుగొనబడలేదు"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ఇన్స్టాల్ చేసిన యాప్ల జాబితాలో యాప్ కనుగొనబడలేదు."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"అనుమతించబడలేదు"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ప్రస్తుత వినియోగదారు ఈ అన్ఇన్స్టాలేషన్ చేసేందుకు అనుమతి లేదు."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"ఎర్రర్"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"అనువర్తనాన్ని అన్ఇన్స్టాల్ చేయడం సాధ్యపడదు."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"యాప్ను అన్ఇన్స్టాల్ చేయండి"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"నవీకరణను అన్ఇన్స్టాల్ చేయండి"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> అనేది క్రింది యాప్లో ఒక భాగం:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"మీరు ఈ యాప్ను అన్ఇన్స్టాల్ చేయాలనుకుంటున్నారా?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"మీరు ఈ యాప్ను "<b>"మొత్తం"</b>" వినియోగదారులకు అన్ఇన్స్టాల్ చేయాలనుకుంటున్నారా? యాప్ మరియు దీని డేటా డివైజ్లోని "<b>"మొత్తం"</b>" వినియోగదారుల నుండి తీసివేయబడుతుంది."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"మీరు వినియోగదారు <xliff:g id="USERNAME">%1$s</xliff:g> కోసం ఈ అనువర్తనాన్ని అన్ఇన్స్టాల్ చేయాలనుకుంటున్నారా?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"ఈ అనువర్తనాన్ని ఫ్యాక్టరీ సంస్కరణతో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ఈ అనువర్తనాన్ని ఫ్యాక్టరీ సంస్కరణతో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది. దీని ప్రభావం కార్యాలయ ప్రొఫైల్లు కలిగి ఉన్నవారితో సహా ఈ పరికర వినియోగదారులందరిపై ఉంటుంది."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"అమల్లో ఉన్న అన్ఇన్స్టాల్లు"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"విఫలమైన అన్ఇన్స్టాల్లు"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"అన్ఇన్స్టాల్ చేస్తోంది…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని అన్ఇన్స్టాల్ చేస్తోంది…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"అన్ఇన్స్టాల్ చేయడం ముగిసింది."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"అన్ఇన్స్టాల్ చేసిన <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"అన్ఇన్స్టాల్ చేయడం విజయవంతం కాలేదు."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> అన్ఇన్స్టాల్ చేయడంలో విఫలమైంది."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"సక్రియ పరికర నిర్వాహక అనువర్తనాన్ని అన్ఇన్స్టాల్ చేయడం సాధ్యపడదు"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> కోసం సక్రియ పరికర నిర్వాహక అనువర్తనాన్ని అన్ఇన్స్టాల్ చేయడం సాధ్యపడదు"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ఈ యాప్ కొందరు వినియోగదారులకు లేదా కొన్ని ప్రొఫైల్లకు అవసరం, ఇతరులకు అన్ఇన్స్టాల్ చేయబడింది"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"మీ ప్రొఫైల్ కోసం ఈ యాప్ అవసరం మరియు దీన్ని అన్ఇన్స్టాల్ చేయలేరు."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"మీ డివైజ్ నిర్వాహకుడికి ఈ యాప్ అవసరం, అందువల్ల దీన్ని అన్ఇన్స్టాల్ చేయడం కుదరదు."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"పరికర నిర్వాహక అనువర్తనాలను నిర్వహించు"</string>
+ <string name="manage_users" msgid="3125018886835668847">"వినియోగదారులను నిర్వహించు"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని అన్ఇన్స్టాల్ చేయడం సాధ్యపడలేదు."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ప్యాకేజీని అన్వయించడంలో సమస్య ఏర్పడింది."</string>
+ <string name="newPerms" msgid="6039428254474104210">"కొత్తవి"</string>
+ <string name="allPerms" msgid="1024385515840703981">"అన్నీ"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"గోప్యత"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"పరికరం యాక్సెస్"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"ఈ నవీకరణకు కొత్త అనుమతులు అవసరం లేదు."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"తిరస్కరించు"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"మరింత సమాచారం"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ఏదేమైనా నిరాకరించు"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>లో <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ని <xliff:g id="ACTION">%2$s</xliff:g> అనుమతించాలా?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<xliff:g id="ACTION">%2$s</xliff:g> చేయడానికి <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>ను ఎల్లప్పుడూ అనుమతించాలా?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"యాప్ను ఉపయోగిస్తున్నప్పుడు మాత్రమే"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ఎల్లప్పుడూ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"నిరాకరించు, మళ్లీ అడగవద్దు"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> నిలిపివేయబడ్డాయి"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"అన్నీ నిలిపివేయబడ్డాయి"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ఏవీ నిలిపివేయబడలేదు"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"అనుమతించు"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"యాప్లు"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"యాప్ అనుమతులు"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"మళ్లీ అడగవద్దు"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"అనుమతులు లేవు"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"అదనపు అనుమతులు"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"యాప్ సమాచారాన్ని తెరుస్తుంది"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">మరో <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="one">మరో <xliff:g id="COUNT_0">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ఈ యాప్ పాత Android వెర్షన్ కోసం రూపొందించబడింది. అనుమతిని నిరాకరించినట్లయితే ఇది ఇకపై ఉద్దేశించిన రీతిలో పని చేయకపోవచ్చు."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"తెలియని చర్యను చేస్తుంది"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>లో <xliff:g id="COUNT_0">%1$d</xliff:g> యాప్లు అనుమతించబడ్డాయి"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"సిస్టమ్ను చూపు"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"సిస్టమ్ను దాచు"</string>
+ <string name="no_apps" msgid="1965493419005012569">"అనువర్తనాలు లేవు"</string>
+ <string name="location_settings" msgid="1774875730854491297">"స్థాన సెట్టింగ్లు"</string>
+ <string name="location_warning" msgid="8778701356292735971">"ఈ పరికరం కోసం స్థాన సేవల ప్రదాత <xliff:g id="APP_NAME">%1$s</xliff:g>. స్థాన సెట్టింగ్ల నుండి స్థాన ప్రాప్యతను సవరించవచ్చు."</string>
+ <string name="system_warning" msgid="7103819124542305179">"మీరు ఈ అనుమతిని నిరాకరిస్తే, మీ పరికర ప్రాథమిక లక్షణాలు ఇకపై ఉద్దేశించిన రీతిలో పని చేయకపోవచ్చు."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"విధానం ద్వారా అమలు చేయబడింది"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"విధానం ద్వారా నేపథ్య యాక్సెస్ నిలిపివేయబడింది"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"విధానం ద్వారా నేపథ్య యాక్సెస్ ప్రారంభించబడింది"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"విధానం ద్వారా ముందుభాగం యాక్సెస్ ప్రారంభించబడింది"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"నిర్వాహకుల నియంత్రణలో ఉంటాయి"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ఎల్లప్పుడూ"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"యాప్ను ఉపయోగిస్తున్నప్పుడు మాత్రమే"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ఎన్నడూ వద్దు"</string>
+ <string name="loading" msgid="7811651799620593731">"లోడ్ అవుతోంది..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"అన్ని అనుమతులు"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"ఇతర అనువర్తన సామర్థ్యాలు"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"అనుమతి అభ్యర్థన"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"స్క్రీన్ అతివ్యాప్తి గుర్తించబడింది"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ఈ అనుమతి సెట్టింగ్ను మార్చడానికి, మీరు ముందుగా సెట్టింగ్లు > అనువర్తనాల నుండి స్క్రీన్ అతివ్యాప్తిని ఆఫ్ చేయాలి"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"సెట్టింగ్లను తెరువు"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android వేర్"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wearలో ఇన్స్టాల్/అన్ఇన్స్టాల్ చర్యలకు మద్దతు లేదు."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> యాక్సెస్ చేయడానికి అనుమతించాల్సిన వాటిని ఎంచుకోండి"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> అప్డేట్ చేయబడింది. ఈ యాప్ యాక్సెస్ చేయడానికి అనుమతించాల్సిన వాటిని ఎంచుకోండి."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"రద్దు చేయి"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"కొనసాగించు"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"కొత్త అనుమతులు"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"ప్రస్తుత అనుమతులు"</string>
+ <string name="message_staging" msgid="6151794817691100003">"అనువర్తనాన్ని అందిస్తోంది…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"తెలియదు"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"మీకు భద్రతను అందించడం కోసం, ఈ మూలం నుండి తెలియని యాప్లను ఇన్స్టాల్ చేయడానికి మీ టాబ్లెట్ అనుమతించబడదు."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"మీకు భద్రతను అందించడం కోసం, ఈ మూలం నుండి తెలియని యాప్లను ఇన్స్టాల్ చేయడానికి మీ TV అనుమతించబడదు."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"మీకు భద్రతను అందించడం కోసం, ఈ మూలం నుండి తెలియని యాప్లను ఇన్స్టాల్ చేయడానికి మీ ఫోన్ అనుమతించబడదు."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"మీ ఫోన్ మరియు వ్యక్తిగత డేటా తెలియని మూలాల్లోని అనువర్తనాల ద్వారా దాడికి గురి కావడానికి ఎక్కువ అవకాశం ఉంటుంది. ఈ అనువర్తనాన్ని ఇన్స్టాల్ చేయడం ద్వారా, ఈ అనువర్తనాన్ని ఉపయోగించడం వలన మీ ఫోన్కు సంభవించే ఏదైనా నష్టానికి లేదా కోల్పోయే డేటాకి బాధ్యత వహించడానికి మీరు అంగీకరిస్తున్నారు."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"మీ టాబ్లెట్ మరియు వ్యక్తిగత డేటా తెలియని మూలాల్లోని అనువర్తనాల ద్వారా దాడికి గురి కావడానికి ఎక్కువ అవకాశం ఉంటుంది. ఈ అనువర్తనాన్ని ఇన్స్టాల్ చేయడం ద్వారా, ఈ అనువర్తనాన్ని ఉపయోగించడం ద్వారా మీ టాబ్లెట్కు సంభవించే ఏదైనా నష్టానికి లేదా కోల్పోయే డేటాకి బాధ్యత వహించడానికి మీరు అంగీకరిస్తున్నారు."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"మీ TV మరియు వ్యక్తిగత డేటా తెలియని మూలాల్లోని అనువర్తనాల ద్వారా దాడికి గురి కావడానికి ఎక్కువ అవకాశం ఉంటుంది. ఈ అనువర్తనాన్ని ఇన్స్టాల్ చేయడం ద్వారా, ఈ అనువర్తనాన్ని ఉపయోగించడం ద్వారా మీ TVకి సంభవించే ఏదైనా నష్టానికి లేదా కోల్పోయే డేటాకి బాధ్యత వహించడానికి మీరు అంగీకరిస్తున్నారు."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"కొనసాగించు"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"సెట్టింగ్లు"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"వేర్ ఆప్లను ఇన్స్టాల్/అన్ఇన్స్టాల్ చేస్తోంది"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-television/colors.xml b/packages/PackageInstaller/res/values-television/colors.xml
new file mode 100644
index 0000000..1cacc00
--- /dev/null
+++ b/packages/PackageInstaller/res/values-television/colors.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+
+ <color name="lb_content_title_text_color">#FFF1F1F1</color>
+ <color name="lb_content_breadcrumb_text_color">#88F1F1F1</color>
+ <color name="lb_content_description_text_color">#88F1F1F1</color>
+ <color name="lb_action_fragment_background">#FF111111</color>
+ <color name="lb_dialog_activity_background">#77000000</color>
+
+ <color name="lb_header_banner_color">#1f292d</color>
+
+ <color name="off_white">#ffeeeeee</color>
+</resources>
diff --git a/packages/PackageInstaller/res/values-television/dimens.xml b/packages/PackageInstaller/res/values-television/dimens.xml
new file mode 100644
index 0000000..d1c232e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-television/dimens.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <dimen name="action_dialog_z">16dp</dimen>
+ <dimen name="action_dialog_padding_left">52dp</dimen>
+ <dimen name="action_dialog_padding_right">40dp</dimen>
+ <dimen name="action_dialog_padding_top">41dp</dimen>
+ <dimen name="action_dialog_padding_bottom">27dp</dimen>
+
+ <dimen name="action_dialog_content_margin_left">24dp</dimen>
+ <dimen name="action_dialog_content_margin_right">32dp</dimen>
+
+ <dimen name="action_dialog_actions_width">304dp</dimen>
+ <dimen name="action_dialog_actions_margin_left">24dp</dimen>
+ <dimen name="action_dialog_actions_margin_top">18dp</dimen>
+
+ <dimen name="action_dialog_button_padding_left">16dp</dimen>
+ <dimen name="action_dialog_button_padding_right">16dp</dimen>
+ <dimen name="action_dialog_button_padding_top">14dp</dimen>
+ <dimen name="action_dialog_button_padding_bottom">15dp</dimen>
+ <dimen name="action_dialog_button_min_height">48dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-th-television/strings.xml b/packages/PackageInstaller/res/values-th-television/strings.xml
new file mode 100644
index 0000000..042a6f1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-th-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"ปฏิเสธและไม่ต้องถามอีก"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"คุณสามารถเปลี่ยนได้ภายหลังในการตั้งค่า > แอป"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"แสดงแอประบบ"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"สิทธิ์ของแอป"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"สิทธิ์ของแอป"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"สิทธิ์เข้าถึง \"<xliff:g id="PERMISSION">%1$s</xliff:g>\""</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"สิทธิ์เพิ่มเติม"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"สิทธิ์เข้าถึง \"<xliff:g id="PERMISSION">%1$s</xliff:g>\""</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-th-watch/strings.xml b/packages/PackageInstaller/res/values-th-watch/strings.xml
new file mode 100644
index 0000000..05af1e8
--- /dev/null
+++ b/packages/PackageInstaller/res/values-th-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"ปฏิเสธ ไม่ต้องถามอีก"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"แสดงแอประบบ"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ไม่สามารถเปลี่ยน"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ใช่"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"ยกเลิก"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml
new file mode 100644
index 0000000..b7735a7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-th/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"โปรแกรมติดตั้งแพ็กเกจ"</string>
+ <string name="next" msgid="3057143178373252333">"ถัดไป"</string>
+ <string name="install" msgid="5896438203900042068">"ติดตั้ง"</string>
+ <string name="done" msgid="3889387558374211719">"เสร็จสิ้น"</string>
+ <string name="cancel" msgid="8360346460165114585">"ยกเลิก"</string>
+ <string name="installing" msgid="8613631001631998372">"กำลังติดตั้ง..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"กำลังติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ติดตั้งแอปพลิเคชันแล้ว"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"คุณต้องการติดตั้งแอปพลิเคชันนี้หรือไม่ แอปพลิเคชันจะเข้าถึง:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"คุณต้องการจะติดตั้งแอปพลิเคชันนี้หรือไม่ แอปพลิเคชันไม่ต้องมีการเข้าถึงพิเศษใดๆ"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"คุณต้องการติดตั้งการอัปเดตของแอปพลิเคชันที่มีอยู่นี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหายไป แอปพลิเคชันที่อัปเดตแล้วจะเข้าถึง:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"คุณต้องการจะติดตั้งการอัปเดตของแอปพลิเคชันในระบบนี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหาย แอปพลิเคชันที่อัปเดตแล้วจะเข้าถึง:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"คุณต้องการติดตั้งการอัปเดตไปยังแอปพลิเคชันที่มีอยู่นี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหาย การอัปเดตนี้ไม่จำเป็นต้องใช้การเข้าถึงใดๆ เป็นพิเศษ"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"คุณต้องการติดตั้งการอัปเดตไปยังแอปพลิเคชันในตัวนี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหาย การอัปเดตนี้ไม่จำเป็นต้องใช้การเข้าถึงใดๆ เป็นพิเศษ"</string>
+ <string name="install_failed" msgid="6579998651498970899">"ไม่ได้ติดตั้งแอปพลิเคชัน"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"มีการบล็อกแพ็กเกจไม่ให้ติดตั้ง"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ไม่ได้ติดตั้งแอปเพราะแพ็กเกจขัดแย้งกับแพ็กเกจที่มีอยู่"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ไม่ได้ติดตั้งแอปเพราะแอปใช้งานไม่ได้กับแท็บเล็ตของคุณ"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"แอปนี้ไม่สามารถใช้งานกับทีวีของคุณ"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ไม่ได้ติดตั้งแอปเพราะแอปใช้งานไม่ได้กับโทรศัพท์ของคุณ"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ไม่ได้ติดตั้งแอปเพราะดูเหมือนว่าแพ็กเกจจะไม่ถูกต้อง"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ไม่สามารถติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> บนแท็บเล็ตของคุณ"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่สามารถติดตั้งบนทีวีได้"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"ไม่สามารถติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> บนโทรศัพท์ของคุณ"</string>
+ <string name="launch" msgid="4826921505917605463">"เปิด"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ผู้ดูแลระบบของคุณไม่อนุญาตให้ติดตั้งแอปที่ได้มาจากแหล่งที่มาที่ไม่รู้จัก"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ผู้ใช้รายนี้ไม่สามารถติดตั้งแอปที่ไม่รู้จัก"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ผู้ใช้รายนี้ไม่ได้รับอนุญาตให้ติดตั้งแอป"</string>
+ <string name="ok" msgid="3468756155452870475">"ตกลง"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"จัดการแอปพลิเคชัน"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ไม่มีพื้นที่"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"ติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> ไม่ได้ เพิ่มพื้นที่ว่างแล้วลองอีกครั้ง"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ไม่พบแอปพลิเคชัน"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ไม่พบแอปพลิเคชันนี้ในรายการแอปพลิเคชันที่ติดตั้งไว้"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ไม่ได้รับอนุญาต"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ผู้ใช้ปัจจุบันไม่ได้รับอนุญาตให้ทำการถอนการติดตั้งนี้"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"พบข้อผิดพลาด"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ไม่สามารถถอนการติดตั้งแอป"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ถอนการติดตั้งแอปพลิเคชัน"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"ถอนการติดตั้งการอัปเดต"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> เป็นส่วนหนึ่งของแอปพลิเคชันต่อไปนี้:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"คุณต้องการถอนการติดตั้งแอปพลิเคชันนี้หรือไม่"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"คุณต้องการถอนการติดตั้งแอปพลิเคชันนี้สำหรับผู้ใช้"<b>"ทั้งหมด"</b>"หรือไม่ แอปพลิเคชันนี้และข้อมูลในแอปพลิเคชันจะถูกลบจากผู้ใช้"<b>"ทั้งหมด"</b>"ในอุปกรณ์"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"คุณต้องการถอนการติดตั้งแอปนี้สำหรับผู้ใช้ <xliff:g id="USERNAME">%1$s</xliff:g> ไหม"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"แทนที่แอปนี้ด้วยเวอร์ชันเริ่มต้นไหม ระบบจะนำข้อมูลทั้งหมดออก"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"แทนที่แอปนี้ด้วยเวอร์ชันเริ่มต้นไหม ระบบจะนำข้อมูลทั้งหมดออก วิธีนี้ส่งผลต่อผู้ใช้ทุกคนที่ใช้อุปกรณ์เครื่องนี้ รวมทั้งผู้ที่มีโปรไฟล์งาน"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"กำลังเรียกใช้การถอนการติดตั้ง"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"การถอนการติดตั้งที่ล้มเหลว"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"กำลังถอนการติดตั้ง..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"กำลังถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"ถอนการติดตั้งเสร็จแล้ว"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"ถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> แล้ว"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"ถอนการติดตั้งไม่สำเร็จ"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"การถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ไม่สำเร็จ"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ไม่สามารถถอนการติดตั้งแอปผู้ดูแลระบบอุปกรณ์ที่มีการใช้งาน"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"ไม่สามารถถอนการติดตั้งแอปผู้ดูแลระบบอุปกรณ์ที่มีการใช้งานสำหรับ <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"แอปนี้จำเป็นสำหรับผู้ใช้หรือโปรไฟล์บางส่วน และถอนการติดตั้งไปแล้วสำหรับส่วนอื่น"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"แอปนี้จำเป็นสำหรับโปรไฟล์ของคุณและไม่สามารถถอนการติดตั้งได้"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ผู้ดูแลระบบอุปกรณ์กำหนดให้ใช้แอปนี้ และไม่สามารถถอนการติดตั้งได้"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"จัดการแอปผู้ดูแลระบบอุปกรณ์"</string>
+ <string name="manage_users" msgid="3125018886835668847">"จัดการผู้ใช้"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"ไม่สามารถถอดการติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"พบปัญหาในการแยกวิเคราะห์แพ็กเกจ"</string>
+ <string name="newPerms" msgid="6039428254474104210">"ใหม่"</string>
+ <string name="allPerms" msgid="1024385515840703981">"ทั้งหมด"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"ข้อมูลส่วนบุคคล"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"การเข้าถึงอุปกรณ์"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"การอัปเดตนี้ไม่จำเป็นต้องมีการอนุญาตใหม่"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ปฏิเสธ"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ข้อมูลเพิ่มเติม"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ยืนยันการปฏิเสธ"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> จาก <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> รายการ"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>ไหม"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>ทุกครั้งใช่ไหม"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ขณะใช้แอปเท่านั้น"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ตลอดเวลา"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ปฏิเสธและไม่ต้องถามอีก"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"ปิดใช้ <xliff:g id="COUNT">%1$d</xliff:g> สิทธิ์"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"ปิดใช้สิทธิ์ทั้งหมด"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"ไม่มีการปิดใช้สิทธิ์"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"อนุญาต"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"แอป"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"สิทธิ์ของแอป"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"ไม่ต้องถามอีก"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"ไม่มีสิทธิ์"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"สิทธิ์เพิ่มเติม"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"เปิดข้อมูลแอป"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">อีก <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
+ <item quantity="one">อีก <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"แอปนี้ออกแบบมาเพื่อ Android เวอร์ชันเก่า การปฏิเสธสิทธิ์อาจทำให้แอปไม่ทำงานตามที่ต้องการอีกต่อไป"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ดำเนินการทำงานที่ไม่รู้จัก"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"อนุญาตแล้ว <xliff:g id="COUNT_0">%1$d</xliff:g> จาก <xliff:g id="COUNT_1">%2$d</xliff:g> แอป"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"แสดงระบบ"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"ซ่อนระบบ"</string>
+ <string name="no_apps" msgid="1965493419005012569">"ไม่มีแอป"</string>
+ <string name="location_settings" msgid="1774875730854491297">"การตั้งค่าตำแหน่ง"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นผู้ให้บริการตำแหน่งสำหรับอุปกรณ์นี้ คุณสามารถแก้ไขสิทธิ์เข้าถึงตำแหน่งได้จากการตั้งค่าตำแหน่ง"</string>
+ <string name="system_warning" msgid="7103819124542305179">"หากคุณปฏิเสธสิทธิ์นี้ ฟีเจอร์พื้นฐานของอุปกรณ์อาจไม่ทำงานตามที่ควรจะเป็นอีกต่อไป"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"บังคับใช้โดยนโยบาย"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ปิดใช้การเข้าถึงในเบื้องหลังโดยนโยบาย"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"เปิดใช้การเข้าถึงในเบื้องหลังโดยนโยบาย"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"เปิดใช้การเข้าถึงในเบื้องหน้าโดยนโยบาย"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ตลอดเวลา"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"ขณะใช้แอปเท่านั้น"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"ไม่เลย"</string>
+ <string name="loading" msgid="7811651799620593731">"กำลังโหลด…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"สิทธิ์ทั้งหมด"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"ความสามารถอื่นๆ ของแอป"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"คำขอสิทธิ์"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"ตรวจพบการวางซ้อนหน้าจอ"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"ในการเปลี่ยนแปลงการตั้งค่าสิทธิ์นี้ ก่อนอื่น คุณต้องปิดการวางซ้อนหน้าจอที่การตั้งค่า > แอป"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"เปิดการตั้งค่า"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ไม่สามารถติดตั้ง/ถอนการติดตั้งบน Wear"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"โปรดเลือกข้อมูลที่อนุญาตให้ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> เข้าถึง"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"อัปเดต <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> แล้ว โปรดเลือกข้อมูลที่อนุญาตให้แอปนี้เข้าถึง"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"ยกเลิก"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"ต่อไป"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"สิทธิ์ใหม่"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"สิทธิ์ปัจจุบัน"</string>
+ <string name="message_staging" msgid="6151794817691100003">"กำลังปรับสภาพแวดล้อมของแอป…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"ไม่ทราบ"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในแท็บเล็ต"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในทีวี"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในโทรศัพท์"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"โทรศัพท์และข้อมูลส่วนบุคคลของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้เป็นการยอมรับว่าคุณจะรับผิดชอบความเสียหายต่อเครื่องโทรศัพท์หรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"แท็บเล็ตและข้อมูลส่วนบุคคลของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้เป็นการยอมรับว่าคุณจะรับผิดชอบความเสียหายต่อเครื่องแท็บเล็ตหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ทีวีและข้อมูลส่วนบุคคลของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้เป็นการยอมรับว่าคุณจะรับผิดชอบความเสียหายต่อเครื่องทีวีหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"ต่อไป"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"การตั้งค่า"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"กำลังติดตั้ง/ถอนการติดตั้งแอป Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-tl-television/strings.xml b/packages/PackageInstaller/res/values-tl-television/strings.xml
new file mode 100644
index 0000000..df5b98f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-tl-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Tanggihan at huwag nang tatanunging muli"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Mababago mo ito sa ibang pagkakataon sa Mga Setting > Mga App"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Ipakita ang mga app ng system"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Mga pahintulot sa app"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Mga pahintulot sa app"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Mga pahintulot sa <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Mga karagdagang pahintulot"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Mga pahintulot sa <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-tl-watch/strings.xml b/packages/PackageInstaller/res/values-tl-watch/strings.xml
new file mode 100644
index 0000000..8597451
--- /dev/null
+++ b/packages/PackageInstaller/res/values-tl-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Tanggihan, huwag nang tatanunging muli"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Ipakita ang mga app ng system"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Hindi mababago"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Oo"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Kanselahin"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
new file mode 100644
index 0000000..05eba98
--- /dev/null
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Installer ng package"</string>
+ <string name="next" msgid="3057143178373252333">"Susunod"</string>
+ <string name="install" msgid="5896438203900042068">"Mag-install"</string>
+ <string name="done" msgid="3889387558374211719">"Tapos na"</string>
+ <string name="cancel" msgid="8360346460165114585">"Kanselahin"</string>
+ <string name="installing" msgid="8613631001631998372">"Nag-i-install…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Ini-install ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Na-install ang app."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Nais mo bang i-install ang application na ito? Magkakaroon ito ng access sa:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Nais mo bang i-install ang application na ito? Hindi ito nangangailangan ng anumang espesyal na access."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Nais mo bang mag-install ng update sa umiiral nang application na ito? Hindi mawawala ang iyong umiiral nang data. Magkakaroon ng access ang na-update na application sa:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Nais mo bang mag-install ng update sa built-in na application na ito? Hindi mawawala ang iyong umiiral na data. Magkakaroon ng access ang na-update na application sa:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Nais mo bang mag-install ng update sa umiiral na application na ito? Hindi mawawala ang iyong umiiral na data. Hindi ito nangangailangan ng anumang espesyal na access."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Nais mo bang mag-install ng update sa built-in na application na ito? Hindi mawawala ang iyong umiiral na data. Hindi ito nangangailangan ng anumang espesyal na access."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Hindi na-install ang app."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Na-block ang pag-install sa package."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Hindi na-install ang app dahil nagkakaproblema ang package sa isang dati nang package."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Hindi na-install ang app dahil hindi tugma ang app sa iyong tablet."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Hindi compatible ang app na ito sa iyong TV."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Hindi na-install ang app dahil hindi tugma ang app sa iyong telepono."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Hindi na-install ang app dahil lumalabas na di-wasto ang package."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa iyong tablet."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay hindi ma-install sa iyong TV."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa iyong telepono."</string>
+ <string name="launch" msgid="4826921505917605463">"Buksan"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Hindi pinapayagan ng iyong admin ang pag-install ng mga app na nakuha mula sa mga hindi kilalang pinagmulan"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Hindi maaaring mag-install ang user na ito ng mga hindi kilalang app"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Hindi pinapayagan ang user na mag-install ng mga app"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Pamahalaan ang apps"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Wala ng espasyo"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>. Magbakante ng ilang espasyo at subukang muli."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Hindi makita ang app"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Hindi makita ang app sa listahan ng naka-install na apps."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Hindi pinapayagan"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Hindi pinapayagan ang kasalukuyang user na gawin ang pag-uninstall na ito."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Hindi ma-uninstall ang app."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"I-uninstall ang app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"I-uninstall ang update"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"Bahagi ang <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ng sumusunod na app:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Gusto mo bang i-uninstall ang app na ito?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Nais mo bang i-uninstall ang app na ito para sa "<b>"lahat"</b>" ng user? Aalisin ang application at ang data nito mula sa "<b>"lahat"</b>" ng user sa device."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Gusto mo bang i-uninstall ang app na ito para sa user na si <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data. Nakakaapekto ito sa lahat ng user ng device na ito, kasama ang mga may profile sa trabaho."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Mga nasa proseso ng pag-uninstall"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mga hindi na-uninstall"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Ina-uninstall…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Ina-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Natapos ang pag-uninstall."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Na-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Di-matagumpay ang pag-uninstall."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Hindi na-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Hindi ma-uninstall ang aktibong app ng admin ng device"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Hindi ma-uninstall ang aktibong app ng admin ng device para kay <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ang app na ito ay kailangan ng ilang user o profile at na-uninstall na ito sa iba pa"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ang app na ito ay kailangan para sa iyong profile at hindi maaaring i-uninstall."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Kinakailangan app na ito ng administrator ng device mo at di maaari i-uninstall."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Pamahalaan ang mga app ng admin ng device"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Pamahalaan ang mga user"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Nagkaroon ng problema sa pag-parse sa package."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Bago"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Lahat"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Access sa Device"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Walang kinakailangang mga bagong pagpapahintulot ang update na ito."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Tanggihan"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Higit pang impormasyon"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tanggihan pa rin"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ng <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Palaging payagan ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> na <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Habang ginagamit lang ang app"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Palagi"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Tanggihan at huwag nang itanong muli"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ang naka-disable"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"naka-disable lahat"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"walang naka-disable"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Payagan"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Mga App"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Mga pahintulot sa app"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Huwag nang tatanunging muli"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Walang pahintulot"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Mga karagdagang pahintulot"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Buksan ang impormasyon ng app"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> pa</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> pa</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ang app na ito ay idinisenyo para sa mas lumang bersyon ng Android. Kapag tinanggihan ang pahintulot, maaaring hindi na ito gumana ayon sa inaasahan."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"gumawa ng hindi kilalang pagkilos"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Pinapayagan ang <xliff:g id="COUNT_0">%1$d</xliff:g> sa <xliff:g id="COUNT_1">%2$d</xliff:g> (na) app"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Ipakita ang system"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Itago ang system"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Walang mga app"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Mga Setting ng Lokasyon"</string>
+ <string name="location_warning" msgid="8778701356292735971">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay isang provider ng mga serbisyo sa lokasyon para sa device na ito. Mababago ang access sa lokasyon mula sa mga setting ng lokasyon."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Kung tatanggihan mo ang pahintulot na ito, maaaring hindi na gumana ang mga pangunahing feature ng iyong device gaya ng inaasahan."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Ipinapatupad sa pamamagitan ng patakaran"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Na-disable ayon sa patakaran ang pag-access sa background"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Na-enable ayon sa patakaran ang pag-access sa background"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Na-enable ayon sa patakaran ang pag-access sa foreground"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kinokontrol ng admin"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Palagi"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Habang ginagamit lang ang app"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Huwag Kailanman"</string>
+ <string name="loading" msgid="7811651799620593731">"Naglo-load..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Lahat ng pahintulot"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Iba pang mga kakayahan ng app"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Kahilingan sa pagpapahintulot"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Natukoy ang overlay ng screen"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Upang baguhin ang setting ng pahintulot na ito, kailangan mo munang i-off ang overlay ng screen mula sa Mga Setting > Mga App"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Buksan ang mga setting"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Ang mga pagkilos na I-install/I-uninstall ay hindi sinusuportahan sa Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Piliin kung ano ang papayagang i-access ng <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Na-update na ang <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Piliin kung ano ang papayagang i-access ng app na ito."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Kanselahin"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Magpatuloy"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Mga bagong pahintulot"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Mga kasalukuyang pahintulot"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Inihahanda ang app…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Hindi Alam"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sa iyong seguridad, hindi pinapayagan ang tablet mo na mag-install ng mga hindi alam na app mula sa pinagmulang ito."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sa iyong seguridad, hindi pinapayagan ang TV mo na mag-install ng mga hindi alam na app mula sa pinagmulang ito."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sa iyong seguridad, hindi pinapayagan ang telepono mo na mag-install ng mga hindi alam na app mula sa pinagmulang ito."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Mas nanganganib ang iyong telepono at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon ka na ikaw ang responsable sa anumang pinsala sa telepono mo o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Mas nanganganib ang iyong tablet at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon ka na ikaw ang responsable sa anumang pinsala sa tablet mo o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Mas nanganganib ang iyong TV at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon ka na ikaw ang responsable sa anumang pinsala sa TV mo o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Magpatuloy"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Mga Setting"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Ini-install/ina-uninstall ang wear apps"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-tr-television/strings.xml b/packages/PackageInstaller/res/values-tr-television/strings.xml
new file mode 100644
index 0000000..7ed0a68
--- /dev/null
+++ b/packages/PackageInstaller/res/values-tr-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Reddet ve bir daha sorma"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Bu ayarı daha sonra Ayarlar > Uygulamalar\'dan değiştirebilirsiniz"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Sistem uygulamalarını göster"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Uygulama izinleri"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Uygulama izinleri"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> izinleri"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Ek izinler"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> izinleri"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-tr-watch/strings.xml b/packages/PackageInstaller/res/values-tr-watch/strings.xml
new file mode 100644
index 0000000..fbc5b93
--- /dev/null
+++ b/packages/PackageInstaller/res/values-tr-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Reddet, bir daha sorma"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Sistem uygulamalarını göster"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Değiştirilemez"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Evet"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"İptal"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
new file mode 100644
index 0000000..ef7882d
--- /dev/null
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Paket yükleyici"</string>
+ <string name="next" msgid="3057143178373252333">"Sonraki"</string>
+ <string name="install" msgid="5896438203900042068">"Yükle"</string>
+ <string name="done" msgid="3889387558374211719">"Bitti"</string>
+ <string name="cancel" msgid="8360346460165114585">"İptal"</string>
+ <string name="installing" msgid="8613631001631998372">"Yükleniyor…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> yükleniyor…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Uygulama yüklendi."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Bu uygulamayı yüklemek istiyor musunuz? Uygulama şunlara erişebilecektir:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bu uygulamayı yüklemek istiyor musunuz? Herhangi bir özel erişim gerektirmez."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Bu mevcut uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz silinmeyecektir. Güncellenen uygulama şunlara erişebilecektir:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Bu yerleşik uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz silinmeyecektir. Güncellenen uygulama şunlara erişebilecektir:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Bu mevcut uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz kaybolacaktır. Herhangi bir özel erişim gerektirmez."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Bu yerleşik uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz kaybolacaktır. Herhangi bir özel erişim gerektirmez."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Uygulama yüklenmedi."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paketin yüklemesi engellendi."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Paket, mevcut bir paketle çakıştığından uygulama yüklenemedi."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Tabletinizle uyumlu olmadığından uygulama yüklenemedi."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Bu uygulama TV\'niz ile uyumlu değil."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Telefonunuzla uyumlu olmadığından uygulama yüklenemedi."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Paket geçersiz göründüğünden uygulama yüklenemedi."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu tabletinize yüklenemedi."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> TV\'nize yüklenemedi."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu telefonunuza yüklenemedi."</string>
+ <string name="launch" msgid="4826921505917605463">"Aç"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Yöneticiniz, bilinmeyen kaynaklardan edinilen uygulamaların yüklenmesine izin vermiyor"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Bilinmeyen uygulamalar bu kullanıcı tarafından yüklenemez"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Bu kullanıcının uygulama yüklemesine izin verilmiyor"</string>
+ <string name="ok" msgid="3468756155452870475">"Tamam"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Uygulamaları yönet"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Yer kalmadı"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> yüklenemedi. Boş alan açın ve yeniden deneyin."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Uygulama bulunamadı"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Uygulama, yüklü uygulamalar listesinde bulunamadı."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"İzin verilmiyor"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Geçerli kullanıcının bu yüklemeyi kaldırma izni yok."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Hata"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Uygulamanın yüklemesi kaldırılamadı."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Uygulamayı kaldır"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Güncelleme kaldırılsın mı?"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>, şu uygulamanın bir parçasıdır:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Bu uygulamanın yüklemesini kaldırmak istiyor musunuz?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Bu uygulamanın yüklemesini "<b>"tüm"</b>" kullanıcılar için kaldırmak istiyor musunuz? Uygulama ve verileri cihazdan "<b>"tüm"</b>" kullanıcılar için kaldırılacaktır."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı kullanıcı için bu uygulamanın yüklemesini kaldırmak istiyor musunuz?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir. Bu, çalışma profilleri olan kullanıcılar da dahil olmak üzere cihazı kullanan tüm kullanıcıları etkiler."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Devam eden yükleme kaldırma işlemleri"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Başarısız yükleme kaldırma işlemleri"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Kaldırılıyor…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılıyor…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Kaldırma işlemi tamamlandı."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırıldı"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Yükleme kaldırılamadı."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılamadı."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Etkin cihaz yönetimi uygulamasının yüklemesi kaldırılamıyor"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı kullanıcı için etkin cihaz yönetimi uygulamasının yüklemesi kaldırılamıyor"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Bu uygulama bazı kullanıcılar veya profiller için gerekli ve diğerleri için uygulamanın yüklemesi kaldırıldı"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Profiliniz için bu uygulama gerekli ve yüklemesi kaldırılamaz."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Bu uygulama, cihazınızın yöneticisi için gereklidir ve yüklemesi kaldırılamaz."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Cihaz yönetimi uygulamalarını yönet"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Kullanıcıları yönetme"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kaldırılamadı."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketin ayrıştırılmasında bir sorun oluştu."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Yeni"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Tümü"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Gizlilik"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Cihaz Erişimi"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Bu güncelleme yeni izin gerektirmiyor."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Reddet"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Daha fazla bilgi"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Yine de reddet"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uygulamasına <xliff:g id="ACTION">%2$s</xliff:g> izni verilsin mi?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uygulamasına <xliff:g id="ACTION">%2$s</xliff:g> için izin verilsin m?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Sadece uygulama kullanılırken"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Her zaman"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Reddet ve bir daha sorma"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> izin devre dışı"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"tümü devre dışı"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"hiçbiri devre dışı değil"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"İzin ver"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Uygulamalar"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Uygulama izinleri"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Tekrar sorma"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"İzin yok"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Ek izinler"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Uygulama bilgilerini aç"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tane daha</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tane daha</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Bu uygulama, Android\'in daha eski bir sürümü için tasarlandı. İznin reddedilmesi, uygulamanın bundan sonra amaçlandığı gibi çalışmamasına neden olabilir."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"bilinmeyen bir işlem gerçekleştirme"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="COUNT_1">%2$d</xliff:g> uygulamaya izin veriliyor"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Sistemi göster"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Sistemi gizle"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Uygulama yok"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Konum Ayarları"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g>, bu cihaz için konum hizmetlerinin bir sağlayıcısıdır. Konum erişimi, konum ayarlarından değiştirilebilir."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Bu izni reddederseniz cihazınızın temel özellikleri artık beklendiği gibi çalışmayabilir."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Politika tarafından zorunlu tutuldu"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Arka plan erişimi politika tarafından devre dışı bırakıldı"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Arka plan erişimi politika tarafından etkinleştirildi"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ön plan erişimi politika tarafından etkinleştirildi"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Yönetici tarafından kontrol ediliyor"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Her zaman"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Sadece uygulama kullanılırken"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Hiçbir zaman"</string>
+ <string name="loading" msgid="7811651799620593731">"Yükleniyor..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Tüm izinler"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Diğer uygulama özellikleri"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"İzin isteği"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Ekran yer paylaşımı tespit edildi"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Bu izin ayarını değiştirmek için ilk olarak Ayarlar > Uygulamalar\'dan ekran yer paylaşımını kapatmanız gerekir"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Ayarları aç"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Yükleme/Yüklemeyi Kaldırma işlemleri Wear\'da desteklenmiyor."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uygulamasının nelere erişmesine izin vereceğinizi seçin"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> güncellendi. Bu uygulamanın nelere erişmesine izin verileceğini seçin."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"İptal"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Devam"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Yeni izinler"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Geçerli izinler"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Uygulama hazırlanıyor…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Bilinmiyor"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Güvenlik nedeniyle tabletinizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Güvenlik nedeniyle TV\'nizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Güvenlik nedeniyle telefonunuzun bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonunuz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı telefonunuzda oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tabletiniz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı tabletinizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV\'niz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı TV\'nizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Devam"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Ayarlar"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear uyg. yükleme/yüklemesini kaldırma"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-uk-television/strings.xml b/packages/PackageInstaller/res/values-uk-television/strings.xml
new file mode 100644
index 0000000..f4b002f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-uk-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Відмовити й більше не запитувати"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Можна змінити згодом у меню \"Налаштування\" > \"Додатки\""</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> з <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Показати системні додатки"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Дозволи додатка"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Дозволи додатка"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g>: дозволи"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Додаткові дозволи"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g>: дозволи"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-uk-watch/strings.xml b/packages/PackageInstaller/res/values-uk-watch/strings.xml
new file mode 100644
index 0000000..e539d83
--- /dev/null
+++ b/packages/PackageInstaller/res/values-uk-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Відхилити й більше не запитувати"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> з <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Показати системні додатки"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Не можна змінити"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Так"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Скасувати"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml
new file mode 100644
index 0000000..bdc09df
--- /dev/null
+++ b/packages/PackageInstaller/res/values-uk/strings.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Програма встановлення пакета"</string>
+ <string name="next" msgid="3057143178373252333">"Далі"</string>
+ <string name="install" msgid="5896438203900042068">"Установити"</string>
+ <string name="done" msgid="3889387558374211719">"Готово"</string>
+ <string name="cancel" msgid="8360346460165114585">"Скасувати"</string>
+ <string name="installing" msgid="8613631001631998372">"Встановлення…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Установлюється <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Додаток установлено."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Установити цей додаток? Він отримає такі дозволи:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Установити цей додаток? Йому не потрібні спеціальні дозволи."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Дійсно встановити оновлення для цієї наявної програми? Існуючі дані втрачено не буде. Оновлена програма отримає доступ до:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Дійсно встановити оновлення для цієї вбудованої програми? Існуючі дані втрачено не буде. Оновлена програма отримає доступ до:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Хочете встановити оновлення для наявної програми? Ваші наявні дані не зникнуть. Спеціальний доступ не потрібен."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Хочете встановити оновлення для цієї вбудованої програми? Ваші наявні дані не зникнуть. Спеціальний доступ не потрібен."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Додаток не встановлено."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Встановлення пакета заблоковано."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Додаток не встановлено, оскільки пакет конфліктує з наявним пакетом."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Додаток не встановлено, оскільки він несумісний із вашим планшетом."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Цей додаток несумісний із вашим телевізором."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Додаток не встановлено, оскільки він несумісний із вашим телефоном."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Додаток не встановлено, оскільки пакет недійсний."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити у вашому планшетному ПК."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Не вдалося встановити додаток <xliff:g id="APP_NAME">%1$s</xliff:g> на ваш телевізор."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити у вашому телефоні."</string>
+ <string name="launch" msgid="4826921505917605463">"Відкрити"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ваш адміністратор заборонив установлювати додатки з невідомих джерел"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Цей користувач не може встановлювати невідомі додатки"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Цей користувач не може встановлювати додатки"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Керувати програмами"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Недостат. місця"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити. Звільніть місце та повторіть спробу."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Програму не знайдено"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Програму не знайдено в списку встановлених програм."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Заборонено"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Поточний користувач не може видалити цей додаток."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Помилка"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Не вдалося видалити додаток."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Видалити програму"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Видалити оновлення"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"Дія <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> є частиною такої програми:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Видалити додаток?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Хочете видалити цю програму для "<b>"всіх"</b>" користувачів? Програму та її дані буде видалено для "<b>"всіх"</b>" користувачів цього пристрою."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Видалити цей додаток для користувача <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Відновити заводську версію цього додатка? Усі дані буде видалено."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Відновити заводську версію цього додатка? Усі дані буде видалено. Це вплине на всіх користувачів цього пристрою, зокрема на користувачів із робочими профілями."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активні видалення"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Невиконані видалення"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Видалення..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Видалення додатка <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Видалення завершено."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> видалено"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Видалення не здійснено."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Не вдалося видалити додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Не вдається видалити активний додаток адміністратора пристрою"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Не вдається видалити активний додаток адміністратора пристрою для користувача <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Цей додаток потрібен для деяких користувачів чи профілів, але його було видалено для інших"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Цей додаток потрібен для вашого профілю, тому його не можна видалити."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Цей додаток не можна видалити – не дозволяє адміністратор пристрою."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Керувати додатками адміністратора пристрою"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Керувати користувачами"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо видалити."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Під час аналізу пакету виникла помилка."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Нові"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Усі"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Конфіденційність"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Доступ до пристрою"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Для цього оновлення не потрібні нові дозволи."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Відхилити"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Докладніше"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Усе одно заборонити"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> з <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Дозволити додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Завжди дозволяти додатку <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Лише коли додаток активний"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Завжди"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Відхилити й більше не запитувати"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> скасовано"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"усі скасовано"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"нічого не скасовано"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Дозволити"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Додатки"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Дозволи додатків"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Не запитувати знову"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Немає дозволів"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Додаткові дозволи"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Відкрити інформацію про додаток"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="few">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="many">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ <item quantity="other">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Цей додаток створено для старішої версії ОС Android. Якщо скасувати дозвіл, він може працювати неналежним чином."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"виконувати невідому дію"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Додатки з дозволом: <xliff:g id="COUNT_0">%1$d</xliff:g> з <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Показати системні додатки"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Сховати системні додатки"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Немає додатків"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Налаштування геоданих"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> є постачальником служб локації для цього пристрою. Доступом до місцезнаходження можна керувати в налаштуваннях геоданих."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Якщо скасувати цей дозвіл, основні функції вашого пристрою можуть працювати неналежним чином."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Застосовується правилом"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Доступ у фоновому режимі вимкнено правилом"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Доступ у фоновому режимі ввімкнено правилом"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Доступ в активному режимі ввімкнено правилом"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Керує адміністратор"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Завжди"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Лише коли додаток активний"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Ніколи"</string>
+ <string name="loading" msgid="7811651799620593731">"Завантаження…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Усі дозволи"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Інші дозволи додатка"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Запит на дозвіл"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Виявлено накладання на екрані"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Щоб змінити налаштування цього дозволу, спершу вимкніть накладання на екрані в меню \"Налаштування\" > \"Додатки\""</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Відкрити налаштування"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Дії \"установити\" або \"видалити\" не підтримуються на пристроях Android Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Виберіть, до чого <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> матиме доступ"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> оновлено. Виберіть, до чого цей додаток матиме доступ."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Скасувати"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Продовжити"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Нові дозволи"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Поточні дозволи"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Підготовка додатка…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Невідомо"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"З міркувань безпеки на вашому планшеті заборонено встановлювати невідомі додатки з цього джерела."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"З міркувань безпеки на вашому телевізорі заборонено встановлювати невідомі додатки з цього джерела."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"З міркувань безпеки на вашому телефоні заборонено встановлювати невідомі додатки з цього джерела."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ваш телефон і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження телефона чи втрату даних унаслідок використання додатка."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ваш планшет і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження планшета чи втрату даних унаслідок використання додатка."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ваш телевізор і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження телевізора чи втрату даних унаслідок використання додатка."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Продовжити"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Налаштування"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Встановлення або видалення додатків Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ur-television/strings.xml b/packages/PackageInstaller/res/values-ur-television/strings.xml
new file mode 100644
index 0000000..27089dd
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ur-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"انکار کریں اور دوبارہ مت پوچھیں"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"آپ بعد میں ترتیبات > ایپس میں جا کر اسے تبدیل کرسکتے ہیں"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"سسٹم ایپس دکھائیں"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"ایپ کی اجازتیں"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"ایپ کی اجازتیں"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> اجازتیں"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"اضافی اجازتیں"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> اجازتیں"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ur-watch/strings.xml b/packages/PackageInstaller/res/values-ur-watch/strings.xml
new file mode 100644
index 0000000..197ac84
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ur-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"انکار کریں، دوبارہ مت پوچھیں"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"سسٹم ایپس دکھائیں"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"ناقابل تبدیل"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"ہاں"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"منسوخ کریں"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
new file mode 100644
index 0000000..78135a6
--- /dev/null
+++ b/packages/PackageInstaller/res/values-ur/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"پیکیج انسٹال کنندہ"</string>
+ <string name="next" msgid="3057143178373252333">"اگلا"</string>
+ <string name="install" msgid="5896438203900042068">"انسٹال کریں"</string>
+ <string name="done" msgid="3889387558374211719">"ہو گیا"</string>
+ <string name="cancel" msgid="8360346460165114585">"منسوخ کریں"</string>
+ <string name="installing" msgid="8613631001631998372">"انسٹال کیا جا رہا ہے…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کو انسٹال کیا جا رہا ہے…"</string>
+ <string name="install_done" msgid="3682715442154357097">"ایپ انسٹال ہوگئی۔"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"کیا آپ یہ ایپلیکیشن انسٹال کرنا چاہتے ہیں؟ اس کو مندرجہ ذیل تک رسائی حاصل ہوگی:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"کیا آپ یہ ایپلیکیشن انسٹال کرنا چاہتے ہیں؟ اس کو کوئی خاص رسائی درکار نہیں۔"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"کیا آپ اس موجودہ ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اپ ڈیٹ کردہ ایپلیکیشن کو مندرجہ ذیل تک رسائی حاصل ہوگی:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"کیا آپ پہلے سے شامل اس ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اپ ڈیٹ کردہ ایپلیکیشن کو مندرجہ ذیل تک رسائی حاصل ہوگی:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"کیا آپ اس موجودہ ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اس کو کوئی خاص رسائی درکار نہیں۔"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"کیا آپ پہلے سے شامل اس ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اس کو کوئی خاص رسائی درکار نہیں۔"</string>
+ <string name="install_failed" msgid="6579998651498970899">"ایپ انسٹال نہیں ہوئی۔"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"پیکج کو انسٹال ہونے سے روک دیا گیا۔"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"ایپ کو پیکج کے بطور انسٹال نہیں کیا گیا کیونکہ پیکج ایک موجودہ پیکیج سے متصادم ہے۔"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ایپ انسٹال نہیں ہوئی کیونکہ ایپ آپ کے ٹیبلیٹ کے ساتھ مطابقت پذیر نہیں ہے۔"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"یہ ایپ آپ کے TV کے ساتھ مطابقت پذیر نہیں ہے۔"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ایپ انسٹال نہیں ہوئی کیونکہ ایپ آپ کے فون کے ساتھ مطابقت پذیر نہیں ہے۔"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"ایپ انسٹال نہیں ہوئی کیونکہ پیکیج غلط معلوم ہوتا ہے۔"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو آپ کے ٹیبلیٹ پر انسٹال نہیں کیا جا سکا۔"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو آپ کے TV پر انسٹال نہیں کیا جا سکا۔"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو آپ کے فون پر انسٹال نہیں کیا جا سکا۔"</string>
+ <string name="launch" msgid="4826921505917605463">"کھولیں"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"آپ کا منتظم نامعلوم ذرائع سے اخذ کردہ ایپس کو انسٹال کرنے کی اجازت نہیں دیتا ہے"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"اس صارف کے ذریعے نامعلوم ایپس کو انسٹال نہیں کیا جا سکتا"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"اس صارف کو ایپس انسٹال کرنے کی اجازت نہیں ہے"</string>
+ <string name="ok" msgid="3468756155452870475">"ٹھیک ہے"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"ایپس کا نظم کریں"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"جگہ ختم ہو گئی ہے"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو انسٹال نہیں کیا جا سکا۔ کچھ جگہ خالی کریں اور دوبارہ کوشش کریں۔"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ایپ نہیں ملی"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ایپ انسٹال کردہ ایپس کی فہرست میں نہیں ملی۔"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"اجازت نہیں ہے"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"موجودہ صارف کو اس ان انسٹالیشن کو سرانجام دینے کی اجازت نہیں ہے۔"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"خرابی"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"ایپ ان انسٹال نہیں ہو سکی۔"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"ایپ کو اَن انسٹال کریں"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"اپ ڈیٹ اَن انسٹال کریں"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> درج ذیل ایپ کا حصہ ہے:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"کیا آپ یہ ایپ اَن انسٹال کرنا چاہتے ہیں؟"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"کیا آپ "<b>"سبھی"</b>" صارفین کیلئے یہ ایپ اَن انسٹال کرنا چاہتے ہیں؟ ایپلیکیشن اور اس کا ڈیٹا آلے پر موجود "<b>"سبھی"</b>" صارفین سے ہٹا دیا جائے گا۔"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"کیا آپ اس ایپ کو صارف <xliff:g id="USERNAME">%1$s</xliff:g> کیلئے اَن انسٹال کرنا چاہتے ہیں؟"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"اس ایپ کو فیکٹری ورژن سے تبدیل کریں؟ تمام ڈیٹا ہٹا دیا جائے گا۔"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"اس ایپ کو فیکٹری ورژن سے تبدیل کریں؟ تمام ڈیٹا ہٹا دیا جائے گا۔ اس سے اس آلہ کے تمام صارف متاثر ہوں گے بشمول ان کے جن کے پاس دفتری پروفائلز ہیں۔"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"چل رہے اَن انسٹالس"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ناکام اَن انسٹالس"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"اَن انسٹال ہو رہا ہے…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ان انسٹال ہو رہی ہے…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"اَن انسٹال پورا ہوگیا۔"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ان انسٹال ہو گیا"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"اَن انسٹال ناکام۔"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کو ان انسٹال کرنا کامیاب نہیں ہوا۔"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"فعال آلہ کے منتظم کی ایپ اَن انسٹال نہیں کر سکتے"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"فعال آلہ کے منتظم کی ایپ <xliff:g id="USERNAME">%1$s</xliff:g> کیلئے اَن انسٹال نہیں کر سکتے"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"یہ ایپ کچھ صارفین اور پروفائلوں کیلئے درکار ہے اور دیگر کیلئے ان انسٹال ہو گئی"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"یہ ایپ آپ کے پروفائل کیلئے درکار ہے اور یہ ان انسٹال نہیں ہو سکتی۔"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"یہ ایپ آپ کے آلہ کے منتظم کو درکار ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"آلہ کے منتظم کی ایپس کا نظم کریں"</string>
+ <string name="manage_users" msgid="3125018886835668847">"صارفین کا نظم کریں"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو اَن انسٹال نہیں کیا جا سکا۔"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"پیکیج کو پارس کرنے میں ایک دشواری پیش آگئی۔"</string>
+ <string name="newPerms" msgid="6039428254474104210">"نئی"</string>
+ <string name="allPerms" msgid="1024385515840703981">"سبھی"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"رازداری"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"آلہ کی رسائی"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"اس اپ ڈیٹ کو کوئی نئی اجازتیں درکار نہیں۔"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"مسترد کریں"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"مزید معلومات"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"بہرصورت انکار کریں"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> از <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> کو <xliff:g id="ACTION">%2$s</xliff:g> کی اجازت دیں؟"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"ہمیشہ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> کو <xliff:g id="ACTION">%2$s</xliff:g> کی اجازت دیں؟"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"صرف ایپ استعمال کرنے کے دوران"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"ہمیشہ"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"انکار کریں اور دوبارہ مت پوچھیں"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> غیر فعال ہو گئیں"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"تمام غیر فعال ہو گئیں"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"کچھ بھی غیر فعال نہیں ہوا"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"اجازت دیں"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ایپس"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"ایپ کی اجازتیں"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"دوبارہ مت پوچھیں"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"کوئی اجازتیں نہیں ہیں"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"اضافی اجازتیں"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ایپ کی معلومات کھولیں"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مزید</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> مزید</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"یہ ایپ Android کے ایک پرانے ورژن کیلئے ڈیزائن کی گئی تھی۔ اجازت دینے سے انکار کرنے پر ممکن ہے کہ وہ مزید ٹھیک سے کام نہ کرے۔"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"ایک نامعلوم کارروائی کو انجام دیں"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> میں سے <xliff:g id="COUNT_0">%1$d</xliff:g> ایپس کو اجازت دے دی گئی"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"سسٹم دکھائیں"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"سسٹم چھپائیں"</string>
+ <string name="no_apps" msgid="1965493419005012569">"کوئی ایپس نہیں ہیں"</string>
+ <string name="location_settings" msgid="1774875730854491297">"مقام کی ترتیبات"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> اس آلہ کیلئے مقام کی سروسز کا فراہم کنندہ ہے۔ مقام کی رسائی میں مقام کی ترتیبات سے ترمیم کی جا سکتی ہے۔"</string>
+ <string name="system_warning" msgid="7103819124542305179">"اگرآپ اس اجازت کو مسترد کرتے ہیں تو شاید آپ کے آلہ کی بنیادی خصوصیات ٹھیک سے کام نہ کریں۔"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"پالیسی کی طرف سے نافذ کردہ"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"پالیسی نے پس منظر کی رسائی غیر فعال کر دی ہے"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"پالیسی نے پس منظر کی رسائی فعال کر دی ہے"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"پالیسی نے پیش منظر کی رسائی فعال کر دی ہے"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"کنٹرول کردہ بذریعہ منتظم"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"ہمیشہ"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"صرف ایپ استعمال کرنے کے دوران"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"کبھی نہیں"</string>
+ <string name="loading" msgid="7811651799620593731">"لوڈ ہورہا ہے…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"تمام اجازاتیں"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"دوسری ایپ اہلیتیں"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"اجازت کی درخواست"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"اسکرین اورلے کا پتہ چلا ہے"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"اس اجازت کی ترتیب کو تبدیل کرنے کیلئے آپ کو پہلے ترتیبات > Apps سے سکرین اورلے آف کرنا ہوگا"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"ترتیبات کھولیں"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"\'کاروائیاں انسٹال/ان انسٹال کریں\' Wear پر تعاون یافتہ نہیں ہے۔"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"انتخاب کریں کہ <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> کو کس تک رسائی کی اجازت دینی ہے"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> اپ ڈیٹ ہو گئی ہے۔ انتخاب کریں کہ اس ایپ کو کس تک رسائی کی اجازت دینی ہے۔"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"منسوخ کریں"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"جاری رکھیں"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"نئی اجازتیں"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"موجودہ اجازتیں"</string>
+ <string name="message_staging" msgid="6151794817691100003">"ایپ کی مرحلہ بندی ہو رہی ہے…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"نامعلوم"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"آپ کی سیکیوریٹی کیلئے، آپ کے ٹیبلیٹ کو اس ذریعے سے نامعلوم ایپس انسٹال کرنے کی اجازت نہیں ہے۔"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"آپ کی سیکیوریٹی کیلئے، آپ کے TV کو اس ذریعے سے نامعلوم ایپس انسٹال کرنے کی اجازت نہیں ہے۔"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"آپ کی سیکیوریٹی کیلئے، آپ کے فون کو اس ذریعے سے نامعلوم ایپس انسٹال کرنے کی اجازت نہیں ہے۔"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"آپ کے فون اور ذاتی ڈیٹا کو نامعلوم ایپس کی جانب سے حملے کا زیادہ خطرہ ہے۔ اس ایپ کو انسٹال کر کے، آپ اس بات سے اتفاق کرتے ہیں کہ آپ اس سے اپنے فون کو ہونے والے کسی بھی نقصان یا ڈیٹا کے نقصان کیلئے خود ذمہ دار ہیں۔"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"آپ کے ٹیبلیٹ اور ذاتی ڈیٹا کو نامعلوم ایپس کی جانب سے حملے کا زیادہ خطرہ ہے۔ اس ایپ کو انسٹال کر کے، آپ اس بات سے اتفاق کرتے ہیں کہ آپ اس سے اپنے ٹیبلیٹ کو ہونے والے کسی بھی نقصان یا ڈیٹا کے نقصان کیلئے خود ذمہ دار ہیں۔"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"آپ کے TV اور ذاتی ڈیٹا کو نامعلوم ایپس کی جانب سے حملے کا زیادہ خطرہ ہے۔ اس ایپ کو انسٹال کر کے، آپ اس بات سے اتفاق کرتے ہیں کہ آپ اس سے اپنے TV کو ہونے والے کسی بھی نقصان یا ڈیٹا کے نقصان کیلئے خود ذمہ دار ہیں۔"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"جاری رکھیں"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"ترتیبات"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"wear ایپس کا انسٹال/ان انسٹال کرنا"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-uz-television/strings.xml b/packages/PackageInstaller/res/values-uz-television/strings.xml
new file mode 100644
index 0000000..bcc12ac
--- /dev/null
+++ b/packages/PackageInstaller/res/values-uz-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Rad etilsin va boshqa so‘ralmasin"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Siz buni keyinroq Sozlamalar > Ilovalar bo‘limi orqali ham o‘zgartirishingiz mumkin"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Tizim ilovalarini ko‘rsatish"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Ilova uchun ruxsatlar"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Ilova uchun ruxsatlar"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> uchun ruxsat"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Qo‘shimcha ruxsatlar"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> uchun ruxsat"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-uz-watch/strings.xml b/packages/PackageInstaller/res/values-uz-watch/strings.xml
new file mode 100644
index 0000000..83f8da7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-uz-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Rad etilsin va boshqa so‘ralmasin"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Tizim ilovalarini ko‘rsatish"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"O‘zgartirilmaydi"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Ha"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Bekor qilish"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml
new file mode 100644
index 0000000..15a2e92
--- /dev/null
+++ b/packages/PackageInstaller/res/values-uz/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Paket o‘rnatish vositasi"</string>
+ <string name="next" msgid="3057143178373252333">"Keyingisi"</string>
+ <string name="install" msgid="5896438203900042068">"O‘rnatish"</string>
+ <string name="done" msgid="3889387558374211719">"Tayyor"</string>
+ <string name="cancel" msgid="8360346460165114585">"Bekor qilish"</string>
+ <string name="installing" msgid="8613631001631998372">"O‘rnatilmoqda…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘rnatilmoqda…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Ilova o‘rnatildi."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Bu ilovani o‘rnatmoqchimisiz? U quyidagi ruxsatlarga ega:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bu ilovani o‘rnatmoqchimisiz? U hech qanday maxsus ruxsat talab qilmaydi."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Bu ilova uchun yangilanishni o‘rnatmoqchimisiz? Yangilanganidan keyin u quyidagi ruxsatlarga ega bo‘ladi:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Bu ilova uchun yangilanishni o‘rnatmoqchimisiz? Yangilanganidan keyin u quyidagi ruxsatlarga ega bo‘ladi:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ushbu mavjud ilovaga yangilanish o‘rnatilsinmi? Mavjud ma’lumotlaringiz o‘chib ketmaydi. U hech qanday maxsus ruxsat talab qilmaydi."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ushbu tizim ilovasiga yangilanish o‘rnatilsinmi? Mavjud ma’lumotlaringiz o‘chib ketmaydi. U hech qanday maxsus ruxsat talab qilmaydi."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Ilova o‘rnatilmadi."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Paket o‘rnatilishga qarshi bloklangan."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Paket mavjud paket bilan zid kelganligi uchun ilovani o‘rnatib bo‘lmadi."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Ilova planshetingizga mos kelmaganligi uchun uni o‘rnatib bo‘lmadi."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Bu ilova televizoringiz bilan mos emas."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Ilova telefoningizga mos kelmaganligi uchun uni o‘rnatib bo‘lmadi."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Paket yaroqsiz bo‘lganligi uchun ilovani o‘rnatib bo‘lmadi."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> planshetingizga o‘rnatilmadi."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasini televizoringizga o‘rnatib bo‘lmadi."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> telefoningizga o‘rnatilmadi."</string>
+ <string name="launch" msgid="4826921505917605463">"Ochish"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratoringiz begona manbalardan olingan ilovalarni o‘rnatishga ruxsat bermagan"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Notanish ilovalarni bu foydalanuvchi tomonidan o‘rnatib bo‘lmaydi"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Bu foydalanuvchiga ilovalarni o‘rnatish uchun ruxsat berilmagan"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Ilovalarni boshqarish"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Joy qolmadi"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> o‘rnatilmadi. Xotiradan biroz joy bo‘shating va qaytadan urinib ko‘ring."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Ilova topilmadi"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Ilova o‘rnatilgan ilovalar ro‘yxatidan topilmadi."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ruxsat berilmagan"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Joriy foydalanuvchiga bu o‘chirishni amalga oshirishi uchun ruxsat berilmagan."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Xato"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Ilovani o‘chirib bo‘lmadi"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Ilovani o‘chirish"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Yangilanishni o‘chirish"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> quyidagi ilovaning bir qismidir:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Bu ilova o‘chirib tashlansinmi?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ushbu ilova "<b>"barcha"</b>" foydalanuvchilar uchun o‘chirilsinmi? Ilova va uning ma’lumotlari qurilmadagi "<b>"barcha"</b>" foydalanuvchilardan o‘chib ketadi."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Haqiqatdan ham <xliff:g id="USERNAME">%1$s</xliff:g> foydalanuvchi uchun ushbu ilovani olib tashlamoqchimisiz?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha ma’lumotlar o‘chirib tashlanadi."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha ma’lumotlar o‘chirib tashlanadi. Bu qurilmaning barcha foydalanuvchilariga, jumladan, ularning ishchi profillariga ham ta’sir qiladi."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Davom etayotganlar"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Amalga oshmaganlar"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"O‘chirilmoqda…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirilmoqda…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"O‘chirib tashlandi."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirib tashlandi"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"O‘chirish muvaffaqiyatsizlikka uchradi."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ilovasini o‘chirib bo‘lmadi."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Faol qurilma administratori ilovasini o‘chirib bo‘lmaydi"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> profilida faol qurilma administratori ilovasini o‘chirib bo‘lmaydi"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Bu ilova ba’zi foydalanuvchi yoki profillar uchun zarur, boshqalar uchun esa o‘chirib tashlangan"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Bu ilova profilingiz uchun kerak va uni o‘chirib bo‘lmaydi."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ushbu ilova qurilmangiz ma\'muri tomonidan ishlatiladi, shuning uchun uni olib tashlab bo\'lmaydi."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Qurilma administratori ilovalarini boshqarish"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Foydalanuvchilarni boshqarish"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> o‘chirilmadi."</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketni tahlil qilishda muammo yuz berdi."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Yangi"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Barchasi"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Maxfiylik"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Qurilmalardan foydalanish"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Ushbu yangilanish hech qanday yangi ruxsatlarni talab qilmaydi."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Rad etish"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Batafsil"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Baribir rad etilsin"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ilovasiga <xliff:g id="ACTION">%2$s</xliff:g> uchun ruxsat berilsinmi?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ilovasiga bu amalga bajarishga doim ruxsat berilsinmi: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Faqat ilova ishlatilayotganda"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Har doim"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Rad etilsin va boshqa so‘ralmasin"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> tasi o‘chiq"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"hammasi o‘chiq"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"hech qaysi o‘chirilmagan"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Ruxsat berish"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Ilovalar"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Ilovalar uchun ruxsatlar"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Boshqa so‘ralmasin"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Hech narsa topilmadi"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Qo‘shimcha ruxsatlar"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ilovaga oid ma’lumotni ochish"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">Yana <xliff:g id="COUNT_1">%1$d</xliff:g> ta</item>
+ <item quantity="one">Yana <xliff:g id="COUNT_0">%1$d</xliff:g> ta</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Bu ilova Androidning eskiroq versiyasiga mo‘ljallab ishlab chiqilgan. Agar ruxsat bermasangiz, u kutilganidek ishlamasligi mumkin."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"noma’lum amalni bajarish"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Ruxsat berilgan: <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Tizimga oid jarayonlar"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Tizimga oid jarayonlarni berkitish"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Hech qanday ilova yo‘q"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Joylashuv sozlamalari"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu qurilma uchun joylashuvni aniqlash xizmatini taqdim etuvchi ilova hisoblanadi. Joylashuv ma’lumotlariga kirish vakolatini joylashuv sozlamalaridan o‘zgartirish mumkin."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Agar bu ruxsatni rad qilsangiz, qurilmangizning asosiy funksiyalari bundan buyon kutilganidek ishlamasligi mumkin."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Qoidaga muvofiq"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Fon rejimida kirish qoidaga muvofiq taqiqlangan"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Fon rejimida kirish qoidaga muvofiq yoqilgan"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Faol rejimda kirish qoidaga muvofiq yoqilgan"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Administrator tomonidan boshqariladi"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Har doim"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Faqat ilova ishlatilayotganda"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Hech qachon"</string>
+ <string name="loading" msgid="7811651799620593731">"Yuklanmoqda…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Barcha ruxsatnomalar"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Ilovaning boshqa imkoniyatlari"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Ruxsatnoma so‘rovi"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Boshqa oynalar ustidan ochiladigan ilova aniqlandi"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Bu ruxsatnoma parametrini o‘zgartirish uchun avval Sozlamalar > Ilovalar bo‘limidan ekran ustidan ochilish funksiyasini o‘chirib qo‘ying"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Sozlamalarni ochish"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear qurilmasi o‘rnatish/o‘chirish amallarini qo‘llab-quvvatlamaydi."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> uchun beriladigan ruxsatlarni tanlang"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> yangilandi. Unga beriladigan ruxsatlarni tanlang."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Bekor qilish"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Davom etish"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Yangi ruxsatnomalar"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Joriy ruxsatnomalar"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Kutib turing…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Noma’lum"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Xavfsizlik yuzasidan, planshetingizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Xavfsizlik yuzasidan, televizoringizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Xavfsizlik yuzasidan, telefoningizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefoningiz va shaxsiy ma‘lumotlaringiz notanish ilovalar xujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan telefoningizga yetkaziladigan shikast va ma‘lumotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Planshetingiz va shaxsiy ma‘lumotlaringiz notanish ilovalar xujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan planshetingizga yetkaziladigan shikast va ma‘lumotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV va shaxsiy ma‘lumotlaringiz notanish ilovalar xujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan televizoringizga yetkaziladigan shikast va ma‘lumotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Davom etish"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Sozlamalar"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Wear ilovalarini o‘rnatish/o‘chirish"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-vi-television/strings.xml b/packages/PackageInstaller/res/values-vi-television/strings.xml
new file mode 100644
index 0000000..574bde7
--- /dev/null
+++ b/packages/PackageInstaller/res/values-vi-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Từ chối và không hỏi lại"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Bạn có thể thay đổi cài đặt này sau trong Cài đặt > Ứng dụng"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Hiển thị ứng dụng hệ thống"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Quyền của ứng dụng"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Quyền của ứng dụng"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"Quyền <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Quyền bổ sung"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"Quyền <xliff:g id="PERMISSION">%1$s</xliff:g>"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-vi-watch/strings.xml b/packages/PackageInstaller/res/values-vi-watch/strings.xml
new file mode 100644
index 0000000..d63ef28
--- /dev/null
+++ b/packages/PackageInstaller/res/values-vi-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Từ chối, không hỏi lại"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Hiển thị ứng dụng hệ thống"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Ko thể thay đổi"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Có"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Hủy"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml
new file mode 100644
index 0000000..09998d8
--- /dev/null
+++ b/packages/PackageInstaller/res/values-vi/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Trình cài đặt gói"</string>
+ <string name="next" msgid="3057143178373252333">"Tiếp theo"</string>
+ <string name="install" msgid="5896438203900042068">"Cài đặt"</string>
+ <string name="done" msgid="3889387558374211719">"Xong"</string>
+ <string name="cancel" msgid="8360346460165114585">"Hủy"</string>
+ <string name="installing" msgid="8613631001631998372">"Đang cài đặt…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"Đang cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"Ứng dụng đã được cài đặt."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Bạn có muốn cài đặt ứng dụng này không? Ứng dụng sẽ có quyền truy cập vào:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bạn có muốn cài đặt ứng dụng này không? Ứng dụng này không yêu cầu bất kỳ quyền truy cập đặc biệt nào."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng hiện tại này không? Dữ liệu hiện tại của bạn sẽ không bị mất. Ứng dụng đã cập nhật sẽ có quyền truy cập vào:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng được cài sẵn này không? Dữ liệu hiện tại của bạn sẽ không bị mất. Ứng dụng được cập nhật sẽ có quyền truy cập vào:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng hiện có này không? Dữ liệu hiện có của bạn sẽ không bị mất. Việc cài đặt không yêu cầu bất kỳ quyền truy cập đặc biệt nào."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng cài sẵn này không? Dữ liệu hiện có của bạn sẽ không bị mất. Việc cài đặt không yêu cầu quyền truy cập đặc biệt nào."</string>
+ <string name="install_failed" msgid="6579998651498970899">"Ứng dụng chưa được cài đặt."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Đã chặn cài đặt gói."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Ứng dụng chưa được cài đặt dưới dạng gói xung đột với gói hiện có."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Ứng dụng chưa được cài đặt dưới dạng ứng dụng không tương thích với máy tính bảng của bạn."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ứng dụng này không tương thích với TV của bạn."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Ứng dụng chưa được cài đặt dưới dạng ứng dụng không tương thích với điện thoại của bạn."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Ứng dụng chưa được cài đặt dưới dạng gói dường như không hợp lệ."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g> trên máy tính bảng của bạn."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Không cài đặt được <xliff:g id="APP_NAME">%1$s</xliff:g> trên TV của bạn."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g> trên điện thoại này."</string>
+ <string name="launch" msgid="4826921505917605463">"Mở"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Quản trị viên của bạn không cho phép cài đặt ứng dụng từ nguồn không xác định"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Người dùng này không thể cài đặt ứng dụng không xác định"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Người dùng này không được phép cài đặt ứng dụng"</string>
+ <string name="ok" msgid="3468756155452870475">"OK"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Quản lý ứng dụng"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Hết dung lượng"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g>. Hãy giải phóng dung lượng và thử lại."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Không tìm thấy ứng dụng"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Không tìm thấy ứng dụng trong danh sách các ứng dụng đã cài đặt."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Không được phép"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Người dùng hiện tại không được phép thực hiện quá trình gỡ cài đặt này."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Lỗi"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Không thể gỡ cài đặt ứng dụng."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Gỡ cài đặt ứng dụng"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Gỡ cài đặt cập nhật"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> là một phần của ứng dụng sau:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Bạn có muốn gỡ cài đặt ứng dụng này không?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Bạn có muốn gỡ cài đặt ứng dụng này cho "<b>"tất cả"</b>" người dùng không? Ứng dụng và dữ liệu của ứng dụng sẽ bị xóa khỏi "<b>"tất cả"</b>" người dùng trên thiết bị."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Bạn có muốn gỡ cài đặt ứng dụng này cho người dùng <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa. Điều này ảnh hưởng đến tất cả người dùng thiết bị này, bao gồm cả những người có hồ sơ công việc."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Gỡ cài đặt đang chạy"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Gỡ cài đặt không thành công"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Đang gỡ cài đặt..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Đang gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Gỡ cài đặt đã hoàn tất."</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Đã gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Gỡ cài đặt không thành công."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> không thành công."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Không thể gỡ cài đặt ứng dụng dành cho quản trị viên thiết bị đang hoạt động"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Không thể gỡ cài đặt ứng dụng dành cho quản trị viên thiết bị đang hoạt động cho <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ứng dụng này bắt buộc với một số người dùng hoặc hồ sơ và được gỡ cài đặt cho người khác"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ứng dụng này là cần thiết cho hồ sơ của bạn và không thể gỡ cài đặt."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ứng dụng này được quản trị viên thiết bị của bạn yêu cầu và không thể gỡ cài đặt."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Quản lý ứng dụng quản trị thiết bị"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Quản lý người dùng"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"Không thể gỡ cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Đã xảy ra sự cố khi phân tích cú pháp gói."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Mới"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Tất cả"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Bảo mật"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Truy cập thiết bị"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Bản cập nhật này không yêu cầu quyền mới."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Từ chối"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Thông tin khác"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Vẫn từ chối"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Luôn cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Chỉ khi sử dụng ứng dụng"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Luôn luôn"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Từ chối và không hỏi lại"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"Đã vô hiệu hóa <xliff:g id="COUNT">%1$d</xliff:g>"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"tất cả quyền đều bị vô hiệu hóa"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"không có quyền nào bị vô hiệu hóa"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Cho phép"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Ứng dụng"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Quyền của ứng dụng"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Không hỏi lại"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Không có quyền"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Quyền khác"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Mở thông tin về ứng dụng"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> quyền khác</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> quyền khác</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ứng dụng này được thiết kế cho các phiên bản Android cũ hơn. Từ chối quyền có thể làm cho ứng dụng không còn hoạt động như mong muốn."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"thực hiện hành động không xác định"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"Đã cho phép <xliff:g id="COUNT_0">%1$d</xliff:g> trong số <xliff:g id="COUNT_1">%2$d</xliff:g> ứng dụng"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Hiển thị hệ thống"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Ẩn hệ thống"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Không có ứng dụng"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Cài đặt vị trí"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> là nhà cung cấp dịch vụ vị trí cho thiết bị này. Bạn có thể sửa đổi quyền truy cập vị trí từ cài đặt vị trí."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Nếu bạn từ chối quyền này, các tính năng cơ bản trên thiết bị của bạn có thể không còn hoạt động như dự kiến."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Được thực thi bằng chính sách"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Quyền truy cập nền bị tắt theo chính sách"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Quyền truy cập nền được bật theo chính sách"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Quyền truy cập nền trước được bật theo chính sách"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Do quản trị viên kiểm soát"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Luôn luôn"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Chỉ khi sử dụng ứng dụng"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Không bao giờ"</string>
+ <string name="loading" msgid="7811651799620593731">"Đang tải…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Tất cả các quyền"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Các khả năng khác của ứng dụng"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Yêu cầu quyền"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Đã phát hiện lớp phủ màn hình"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Để thay đổi cài đặt quyền này, trước tiên bạn phải tắt lớp phủ màn hình từ Cài đặt > Ứng dụng"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Mở cài đặt"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Không hỗ trợ tác vụ Cài đặt/Gỡ cài đặt trên Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Chọn cho phép <b><xliff:g id="APP_NAME">%1$s</xliff:g></b> truy cập những gì"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"Đã cập nhật <b><xliff:g id="APP_NAME">%1$s</xliff:g></b>. Chọn cho phép ứng dụng này truy cập những gì."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Hủy"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Tiếp tục"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Các quyền mới"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Các quyền hiện tại"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Đang sắp xếp ứng dụng…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Không xác định"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Để bảo mật, máy tính bảng của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Để bảo mật, TV của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Để bảo mật, điện thoại của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Điện thoại và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với điện thoại của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Máy tính bảng và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với máy tính bảng của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với TV của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Tiếp tục"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Cài đặt"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Cài đặt/gỡ cài đặt ứng dụng Wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-w192dp-watch/dimens_percent.xml b/packages/PackageInstaller/res/values-w192dp-watch/dimens_percent.xml
new file mode 100644
index 0000000..b5beca3
--- /dev/null
+++ b/packages/PackageInstaller/res/values-w192dp-watch/dimens_percent.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="screen_percentage_05">9.6dp</dimen>
+ <dimen name="screen_percentage_10">19.2dp</dimen>
+ <dimen name="screen_percentage_12">23.04dp</dimen>
+ <dimen name="screen_percentage_15">28.8dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-w205dp-watch/dimens_percent.xml b/packages/PackageInstaller/res/values-w205dp-watch/dimens_percent.xml
new file mode 100644
index 0000000..302d23e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-w205dp-watch/dimens_percent.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="screen_percentage_05">10.25dp</dimen>
+ <dimen name="screen_percentage_10">20.5dp</dimen>
+ <dimen name="screen_percentage_12">24.6dp</dimen>
+ <dimen name="screen_percentage_15">30.75dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-w225dp-watch/dimens_percent.xml b/packages/PackageInstaller/res/values-w225dp-watch/dimens_percent.xml
new file mode 100644
index 0000000..937c5d0
--- /dev/null
+++ b/packages/PackageInstaller/res/values-w225dp-watch/dimens_percent.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="screen_percentage_05">11.25dp</dimen>
+ <dimen name="screen_percentage_10">22.5dp</dimen>
+ <dimen name="screen_percentage_12">27dp</dimen>
+ <dimen name="screen_percentage_15">33.75dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-w228dp-watch/dimens_percent.xml b/packages/PackageInstaller/res/values-w228dp-watch/dimens_percent.xml
new file mode 100644
index 0000000..b2ad334
--- /dev/null
+++ b/packages/PackageInstaller/res/values-w228dp-watch/dimens_percent.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="screen_percentage_05">11.4dp</dimen>
+ <dimen name="screen_percentage_10">22.8dp</dimen>
+ <dimen name="screen_percentage_12">27.36dp</dimen>
+ <dimen name="screen_percentage_15">34.2dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-w240dp-watch/dimens_percent.xml b/packages/PackageInstaller/res/values-w240dp-watch/dimens_percent.xml
new file mode 100644
index 0000000..ebc8c75
--- /dev/null
+++ b/packages/PackageInstaller/res/values-w240dp-watch/dimens_percent.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="screen_percentage_05">12dp</dimen>
+ <dimen name="screen_percentage_10">24dp</dimen>
+ <dimen name="screen_percentage_12">28.8dp</dimen>
+ <dimen name="screen_percentage_15">36dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values-watch/colors.xml b/packages/PackageInstaller/res/values-watch/colors.xml
new file mode 100644
index 0000000..81d0459
--- /dev/null
+++ b/packages/PackageInstaller/res/values-watch/colors.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Copied from wearable support -->
+ <color name="circular_button_disabled">#757575</color>
+</resources>
diff --git a/packages/PackageInstaller/res/values-watch/integers.xml b/packages/PackageInstaller/res/values-watch/integers.xml
new file mode 100644
index 0000000..365ac3a
--- /dev/null
+++ b/packages/PackageInstaller/res/values-watch/integers.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- START: Ported values -->
+ <integer name="short_title_length">13</integer>
+ <integer name="char_limit_per_line">18</integer>
+ <!-- END: Ported values -->
+</resources>
diff --git a/packages/PackageInstaller/res/values-watch/strings.xml b/packages/PackageInstaller/res/values-watch/strings.xml
new file mode 100644
index 0000000..25e8389
--- /dev/null
+++ b/packages/PackageInstaller/res/values-watch/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Generic text to indicate a yes. [CHAR LIMIT=10] -->
+ <string name="generic_yes">Yes</string>
+
+ <!-- Generic text to indicate Cancel. [CHAR LIMIT=10] -->
+ <string name="generic_cancel">Cancel</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-watch/styles.xml b/packages/PackageInstaller/res/values-watch/styles.xml
new file mode 100644
index 0000000..805d43d
--- /dev/null
+++ b/packages/PackageInstaller/res/values-watch/styles.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <style name="BreadcrumbText" parent="@android:style/TextAppearance.Material.Body2"/>
+ <style name="TitleText" parent="@android:style/TextAppearance.Material.Subhead"/>
+</resources>
diff --git a/packages/PackageInstaller/res/values-watch/themes.xml b/packages/PackageInstaller/res/values-watch/themes.xml
new file mode 100644
index 0000000..5e52008
--- /dev/null
+++ b/packages/PackageInstaller/res/values-watch/themes.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources>
+ <style name="DialogWhenLarge" parent="@android:style/Theme.DeviceDefault.NoActionBar"/>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rCN-television/strings.xml b/packages/PackageInstaller/res/values-zh-rCN-television/strings.xml
new file mode 100644
index 0000000..9b43370
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rCN-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"拒绝,不要再询问"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"您以后可以在“设置”>“应用”中更改此设置"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"显示系统应用"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"应用权限"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"应用权限"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g>权限"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"其他权限"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g>权限"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rCN-watch/strings.xml b/packages/PackageInstaller/res/values-zh-rCN-watch/strings.xml
new file mode 100644
index 0000000..2525619
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rCN-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"拒绝,不要再询问"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"显示系统应用"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"无法更改"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"是"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"取消"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..d559774
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"软件包安装程序"</string>
+ <string name="next" msgid="3057143178373252333">"下一步"</string>
+ <string name="install" msgid="5896438203900042068">"安装"</string>
+ <string name="done" msgid="3889387558374211719">"完成"</string>
+ <string name="cancel" msgid="8360346460165114585">"取消"</string>
+ <string name="installing" msgid="8613631001631998372">"正在安装..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"正在安装<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"应用安装完成。"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"要安装此应用吗?它将获得以下权限:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"您要安装此应用吗?此应用不需要任何特殊权限。"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"您要安装此应用的新版本吗?您现有的数据不会丢失。更新后的应用将具备以下权限:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"您要安装此内置应用的新版本吗?您现有的数据不会丢失。更新后的应用将具备以下权限:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"是否要为这一现有应用安装更新?您现有的数据不会丢失,且安装过程无需任何特殊权限。"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"是否要为这一内置应用安装更新?您现有的数据不会丢失,且安装过程无需任何特殊权限。"</string>
+ <string name="install_failed" msgid="6579998651498970899">"应用未安装。"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"系统禁止安装该软件包。"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"应用未安装:软件包与现有软件包存在冲突。"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"应用未安装:应用与您的平板电脑不兼容。"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"此应用与您的电视不兼容。"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"应用未安装:应用与您的手机不兼容。"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"应用未安装:软件包似乎无效。"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"无法在您的平板电脑上安装“<xliff:g id="APP_NAME">%1$s</xliff:g>”。"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"无法将<xliff:g id="APP_NAME">%1$s</xliff:g>安装到您的电视上。"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"无法在您的手机上安装“<xliff:g id="APP_NAME">%1$s</xliff:g>”。"</string>
+ <string name="launch" msgid="4826921505917605463">"打开"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"您的管理员不允许安装来源不明的应用"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"该用户无法安装未知应用"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"此用户不能安装应用"</string>
+ <string name="ok" msgid="3468756155452870475">"确定"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"管理应用"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"没有存储空间"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"无法安装“<xliff:g id="APP_NAME">%1$s</xliff:g>”,请释放一些存储空间并重试。"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"未找到应用"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"未在已安装应用的列表中找到该应用。"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"不允许"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"当前用户无法执行这项卸载操作。"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"错误"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"无法卸载应用。"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"卸载应用"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"卸载更新"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>属于以下应用:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"要卸载此应用吗?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"是否要为"<b>"所有"</b>"用户卸载此应用?系统将为设备上的"<b>"所有"</b>"用户删除此应用及其数据。"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"您要为用户<xliff:g id="USERNAME">%1$s</xliff:g>卸载此应用吗?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"要将此应用替换为出厂版本吗?这样会移除所有数据。"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"要将此应用替换为出厂版本吗?这样会移除所有数据,并会影响此设备的所有用户(包括已设置工作资料的用户)。"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"进行中的卸载操作"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"失败的卸载操作"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"正在卸载..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"正在卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"卸载完成。"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"已卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"卸载失败。"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>失败。"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"无法卸载正在使用中的设备管理应用"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"无法为<xliff:g id="USERNAME">%1$s</xliff:g>卸载正在使用中的设备管理应用"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"这是部分用户或个人资料所需的应用;已为其他用户或个人资料卸载此应用"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"这是您的个人资料所需的应用,因此无法卸载。"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"这是您的设备管理员要求必须安装的应用,因此无法卸载。"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"管理设备管理应用"</string>
+ <string name="manage_users" msgid="3125018886835668847">"管理用户"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"无法卸载“<xliff:g id="APP_NAME">%1$s</xliff:g>”。"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"解析软件包时出现问题。"</string>
+ <string name="newPerms" msgid="6039428254474104210">"新权限"</string>
+ <string name="allPerms" msgid="1024385515840703981">"全部"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"隐私相关权限"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"设备相关权限"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"新版本不需要任何新的权限。"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"拒绝"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"详情"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"仍然拒绝"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"第 <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> 项权限(共 <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> 项)"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"要允许<b><xliff:g id="APP_NAME">%1$s</xliff:g></b><xliff:g id="ACTION">%2$s</xliff:g>吗?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"要一律允许<b><xliff:g id="APP_NAME">%1$s</xliff:g></b><xliff:g id="ACTION">%2$s</xliff:g>吗?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"仅限使用应用时"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"一律允许"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"拒绝,不要再询问"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> 项已停用"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"全部已停用"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"均未停用"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"允许"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"应用"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"应用权限"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"不再询问"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"没有权限"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"其他权限"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"打开应用信息"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">另外 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item>
+ <item quantity="one">另外 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"此应用专为旧版 Android 打造。拒绝权限可能会导致其无法正常运行。"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"执行未知操作"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"已授权 <xliff:g id="COUNT_0">%1$d</xliff:g> 个应用(共 <xliff:g id="COUNT_1">%2$d</xliff:g> 个)"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"显示系统应用"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"隐藏系统应用"</string>
+ <string name="no_apps" msgid="1965493419005012569">"没有应用"</string>
+ <string name="location_settings" msgid="1774875730854491297">"位置信息设置"</string>
+ <string name="location_warning" msgid="8778701356292735971">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”是此设备的一个位置信息服务提供程序。您可以在位置信息设置中修改位置信息使用权。"</string>
+ <string name="system_warning" msgid="7103819124542305179">"如果您拒绝此权限,您设备的基本功能可能会无法正常使用。"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"依据政策强制执行"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"已根据政策停用后台访问权限"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"已根据政策启用后台访问权限"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"已根据政策启用前台访问权限"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"由管理员控制"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"一律允许"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"仅限使用应用时"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"永不"</string>
+ <string name="loading" msgid="7811651799620593731">"正在加载…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"所有权限"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"其他应用功能"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"权限请求"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"检测到屏幕叠加层"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"要更改此权限设置,您必须首先在“设置”>“应用”中关闭屏幕叠加层"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"打开设置"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear 不支持安装/卸载操作。"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"请选择要向<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>授予哪些权限"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b>已更新。请选择要向此应用授予哪些权限。"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"取消"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"继续"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"新权限"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"当前权限"</string>
+ <string name="message_staging" msgid="6151794817691100003">"正在准备安装应用…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"未知"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"出于安全考虑,已禁止您的平板电脑安装来自此来源的未知应用。"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"出于安全考虑,已禁止您的电视安装来自此来源的未知应用。"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"出于安全考虑,已禁止您的手机安装来自此来源的未知应用。"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"来历不明的应用很可能会损害您的手机和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何手机损坏或数据丢失情况,您负有全部责任。"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"来历不明的应用很可能会损害您的平板电脑和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何平板电脑损坏或数据丢失情况,您负有全部责任。"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"来历不明的应用很可能会损害您的电视和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何电视损坏或数据丢失情况,您负有全部责任。"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"继续"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"设置"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"正在安装/卸载 Android Wear 应用"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rHK-television/strings.xml b/packages/PackageInstaller/res/values-zh-rHK-television/strings.xml
new file mode 100644
index 0000000..52c3d30
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rHK-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"拒絕,不要再問我"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"您日後可以在 [設定] > [應用程式] 中變更這項設定"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"顯示系統應用程式"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"應用程式權限"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"應用程式權限"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g>權限"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"其他權限"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g>權限"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rHK-watch/strings.xml b/packages/PackageInstaller/res/values-zh-rHK-watch/strings.xml
new file mode 100644
index 0000000..6d0226f
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rHK-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"拒絕,不要再問我"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"顯示系統應用程式"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"不可變更"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"是"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"取消"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..0401eb1
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"程式安裝器"</string>
+ <string name="next" msgid="3057143178373252333">"下一步"</string>
+ <string name="install" msgid="5896438203900042068">"安裝"</string>
+ <string name="done" msgid="3889387558374211719">"完成"</string>
+ <string name="cancel" msgid="8360346460165114585">"取消"</string>
+ <string name="installing" msgid="8613631001631998372">"正在安裝..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"正在安裝 <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"已安裝應用程式。"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"您要安裝這個應用程式嗎?應用程式將取得以下存取權:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"您要安裝這個應用程式嗎?應用程式不需任何特殊存取權。"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"您要為這個現有的應用程式安裝更新嗎?您的現有資料將會喪失,更新後的應用程式將取得以下存取權:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"您要為這個內置的應用程式安裝更新嗎?您的現有資料將會喪失,更新後的應用程式將取得以下存取權:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"您要為這個現有的應用程式安裝更新嗎?您不會遺失現有的資料,而應用程式無需任何特殊的存取權限。"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"您要為這個內置應用程式安裝更新嗎?您不會遺失現有的資料,而應用程式無需任何特殊的存取權限。"</string>
+ <string name="install_failed" msgid="6579998651498970899">"未安裝應用程式。"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"套件已遭封鎖,無法安裝。"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"套件與現有的套件發生衝突,無法安裝應用程式。"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"應用程式與平板電腦不兼容,無法安裝應用程式。"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"此應用程式與您的電視不相容。"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"應用程式與手機不兼容,無法安裝應用程式。"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"套件好像無效,無法安裝應用程式。"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"無法在您的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"無法在您的電視上安裝 <xliff:g id="APP_NAME">%1$s</xliff:g>。"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"無法在您的手機上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+ <string name="launch" msgid="4826921505917605463">"開啟"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"您的管理員不允許安裝來自不明來源的應用程式"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"此使用者無法安裝不明的應用程式"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"此使用者無法安裝應用程式"</string>
+ <string name="ok" msgid="3468756155452870475">"確定"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"管理應用程式"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"空間不足"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"無法解除安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先騰出一些空間,然後再試一次。"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"找不到應用程式"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"在已安裝的應用程式清單中找不到這個應用程式。"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"不允許"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"目前的使用者不允許執行這項解除安裝操作。"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"錯誤"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"應用程式無法解除安裝。"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"解除安裝應用程式"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"解除安裝更新"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"「<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>」隸屬於以下應用程式:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"您要解除安裝這個應用程式嗎?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"您要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔中移除。"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"您要為使用者 <xliff:g id="USERNAME">%1$s</xliff:g> 解除安裝這個應用程式嗎?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"要將此應用程式回復至原廠版本嗎?所有資料將會刪除。"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"要將此應用程式回復至原廠版本嗎?所有資料將會刪除,此裝置的所有使用者 (包括使用工作設定檔的使用者) 亦會受影響。"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"正在執行的解除安裝操作"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"失敗的解除安裝操作"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"正在解除安裝..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"完成解除安裝。"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"解除安裝失敗。"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」失敗。"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"無法解除安裝可用的裝置管理員應用程式"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"無法為<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝可用的裝置管理員應用程式"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"這是部分使用者或設定檔所需的應用程式,其他使用者或設定檔已解除安裝此應用程式"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"這是您設定檔所需的應用程式,因此無法解除安裝。"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"這是您的裝置管理員要求安裝的應用程式,因此無法解除安裝。"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"管理裝置管理員應用程式"</string>
+ <string name="manage_users" msgid="3125018886835668847">"管理使用者"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"無法解除安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"剖析套件時發生問題。"</string>
+ <string name="newPerms" msgid="6039428254474104210">"新增"</string>
+ <string name="allPerms" msgid="1024385515840703981">"全部"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"私隱權"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"裝置存取權"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"這項更新不需新權限。"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"拒絕"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"更多資訊"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"一律拒絕"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"第 <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> 個 (共 <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> 個)"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"要一律允許「<xliff:g id="APP_NAME">%1$s</xliff:g><b></b>」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"只在使用應用程式時"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"一律"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"拒絕,不要再詢問"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> 個權限已停用"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"所有權限已停用"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"沒有權限已停用"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"允許"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"應用程式"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"應用程式權限"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"不要再問我"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"沒有權限"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"其他權限"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"打開應用程式資料"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">還有 <xliff:g id="COUNT_1">%1$d</xliff:g> 個</item>
+ <item quantity="one">還有 <xliff:g id="COUNT_0">%1$d</xliff:g> 個</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"這個應用程式專為舊版本的 Android 設計。拒絕權限可能會導致它無法如預期 運作。"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"執行不明的操作"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"已允許 <xliff:g id="COUNT_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="COUNT_1">%2$d</xliff:g> 個)"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"顯示系統"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"隱藏系統"</string>
+ <string name="no_apps" msgid="1965493419005012569">"沒有應用程式"</string>
+ <string name="location_settings" msgid="1774875730854491297">"位置設定"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g>為此裝置提供位置資訊服務。您可以在位置設定中更改位置存取權。"</string>
+ <string name="system_warning" msgid="7103819124542305179">"如果您拒絕這個權限,您的裝置的基本功能可能無法正常運作。"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"由政策強制執行"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"已根據政策停用背景存取權"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"已根據政策啟用背景存取權"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"已根據政策啟用前景存取權"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"由管理員控制"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"一律"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"只在使用應用程式時"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"永不"</string>
+ <string name="loading" msgid="7811651799620593731">"正在載入…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"所有權限"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"其他應用程式功能"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"權限要求"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"已偵測到螢幕重疊功能"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"如要變更此權限設定,請先前往 [設定] > [應用程式],以關閉螢幕重疊功能"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"開啟設定"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear 不支援安裝/解除安裝操作。"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"選擇允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取的內容"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"已更新「<xliff:g id="APP_NAME">%1$s</xliff:g>」。選擇允許此應用程式存取的內容。"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"取消"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"繼續"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"新權限"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"目前權限"</string>
+ <string name="message_staging" msgid="6151794817691100003">"正在準備安裝應用程式…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"不明"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"為安全起見,您的平板電腦不得安裝此來源的不明應用程式。"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"為安全起見,您的電視不得安裝此來源的不明應用程式。"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"為安全起見,您的手機不得安裝此來源的不明應用程式。"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"來源不明的應用程式可能會侵害您的手機和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致手機損壞或資料遺失的責任。"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"來源不明的應用程式可能會侵害您的平板電腦和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致平板電腦損壞或資料遺失的責任。"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"來源不明的應用程式可能會侵害您的電視和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致電視損壞或資料遺失的責任。"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"繼續"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"設定"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"正在安裝/解除安裝 Wear 應用程式"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rTW-television/strings.xml b/packages/PackageInstaller/res/values-zh-rTW-television/strings.xml
new file mode 100644
index 0000000..59266f9
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rTW-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"拒絕且不要再詢問"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"你日後可在 [設定] > [應用程式] 中進行變更"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"顯示系統應用程式"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"應用程式權限"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"應用程式權限"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g>權限"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"其他權限"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g>權限"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rTW-watch/strings.xml b/packages/PackageInstaller/res/values-zh-rTW-watch/strings.xml
new file mode 100644
index 0000000..edaf7ea
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rTW-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"拒絕且不要再詢問"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"顯示系統應用程式"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"無法變更"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"是"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"取消"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..db96924
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"程式安裝器"</string>
+ <string name="next" msgid="3057143178373252333">"下一步"</string>
+ <string name="install" msgid="5896438203900042068">"安裝"</string>
+ <string name="done" msgid="3889387558374211719">"完成"</string>
+ <string name="cancel" msgid="8360346460165114585">"取消"</string>
+ <string name="installing" msgid="8613631001631998372">"安裝中…"</string>
+ <string name="installing_app" msgid="4097935682329028894">"正在安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
+ <string name="install_done" msgid="3682715442154357097">"已安裝應用程式。"</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"你要安裝這個應用程式嗎?應用程式將取得以下權限:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"你要安裝這個應用程式嗎?應用程式不需任何特殊權限。"</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"你要為這個現有的應用程式安裝更新嗎?你的現有資料不會遺失,而更新後的應用程式將取得以下權限:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"你要為這個內建的應用程式安裝更新嗎?你的現有資料不會遺失,而更新後的應用程式將取得以下權限:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"你要為這個現有的應用程式安裝更新嗎?你不會遺失現有的資料,且應用程式不需任何特殊權限。"</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"你要為這個現有的內建應用程式安裝更新嗎?你不會遺失現有的資料,且應用程式不需任何特殊權限。"</string>
+ <string name="install_failed" msgid="6579998651498970899">"未安裝應用程式。"</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"這個套件已遭到封鎖,因此無法安裝。"</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"應用程式套件與現有套件衝突,因此未能完成安裝。"</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"應用程式與你的平板電腦不相容,因此未能完成安裝。"</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"這個應用程式與你的電視不相容。"</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"應用程式與你的手機不相容,因此未能完成安裝。"</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"應用程式套件無效,因此未能完成安裝。"</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"無法在你的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"無法在你的電視上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"無法在你的手機上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+ <string name="launch" msgid="4826921505917605463">"開啟"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"你的管理員不允許安裝來源不明的應用程式"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"這位使用者無法安裝不明的應用程式"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"這位使用者無法安裝應用程式"</string>
+ <string name="ok" msgid="3468756155452870475">"確定"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"管理應用程式"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"空間不足"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"無法安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先釋出部分空間,然後再試一次。"</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"找不到應用程式"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"在已安裝的應用程式清單中找不到這個應用程式。"</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"不允許此操作"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"目前的使用者無法執行這項解除安裝作業。"</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"發生錯誤"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"無法解除安裝應用程式。"</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"解除安裝應用程式"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"解除安裝更新"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"「<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>」屬於下列應用程式:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"你要解除安裝這個應用程式嗎?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"你要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?該應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔移除。"</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"你要為使用者 <xliff:g id="USERNAME">%1$s</xliff:g> 解除安裝這個應用程式嗎?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"要將應用程式換成原廠版本嗎?這麼做會移除所有資料。"</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"要將應用程式換成原廠版本嗎?這麼做會移除所有資料。凡是這個裝置的使用者 (包括設置工作資料夾的使用者),皆會受到影響。"</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"執行中的解除安裝作業"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"失敗的解除安裝作業"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"解除安裝中…"</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"解除安裝完成。"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"解除安裝失敗。"</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"無法解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」。"</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"無法解除安裝使用中的裝置管理員應用程式"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"無法為<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝使用中的裝置管理員應用程式"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"部分使用者或設定檔需要使用這個應用程式;已為其他使用者解除安裝"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"你的設定檔需要使用這個應用程式,因此無法解除安裝。"</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"這是你的裝置管理員要求安裝的應用程式,因此無法解除安裝。"</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"管理裝置管理員應用程式"</string>
+ <string name="manage_users" msgid="3125018886835668847">"管理使用者"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"無法解除安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"剖析套件時發生問題。"</string>
+ <string name="newPerms" msgid="6039428254474104210">"新增"</string>
+ <string name="allPerms" msgid="1024385515840703981">"全部"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"隱私權"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"裝置存取權"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"這項更新不需新權限。"</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"拒絕"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"瞭解詳情"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"直接拒絕"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"要一律允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"僅限使用應用程式時"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"一律允許"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"拒絕且不要再詢問"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"已停用 <xliff:g id="COUNT">%1$d</xliff:g> 項權限"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"已停用所有權限"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"未停用任何權限"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"允許"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"應用程式"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"應用程式權限"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"不要再詢問"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"沒有權限"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"其他權限"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"開啟應用程式資訊"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="other">還有 <xliff:g id="COUNT_1">%1$d</xliff:g> 項</item>
+ <item quantity="one">還有 <xliff:g id="COUNT_0">%1$d</xliff:g> 項</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"這個應用程式是為舊版 Android 所開發。拒絕授予權限可能導致應用程式無法正常運作。"</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"執行不明的動作"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"已授權 <xliff:g id="COUNT_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="COUNT_1">%2$d</xliff:g> 個)"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"顯示系統"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"隱藏系統"</string>
+ <string name="no_apps" msgid="1965493419005012569">"沒有應用程式"</string>
+ <string name="location_settings" msgid="1774875730854491297">"位置資訊設定"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> 是這台裝置的定位服務供應商。你可以在位置資訊設定中修改位置資訊存取權。"</string>
+ <string name="system_warning" msgid="7103819124542305179">"如果你拒絕這項權限,裝置的基本功能可能無法正常運作。"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"依據政策規定執行"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"已根據政策停用背景存取權"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"已根據政策啟用背景存取權"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"已根據政策啟用前景存取權"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"由管理員控管"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"一律允許"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"僅限使用應用程式時"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"永不"</string>
+ <string name="loading" msgid="7811651799620593731">"載入中…"</string>
+ <string name="all_permissions" msgid="5156669007784613042">"所有權限"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"其他應用程式功能"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"權限要求"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"偵測到畫面重疊圖層"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"如要變更這項權限設定,你必須先依序前往 [設定] > [應用程式],關閉裝置畫面重疊圖層"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"開啟設定"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear 不支援安裝及解除安裝操作。"</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"選擇要將哪些存取權限授予「<xliff:g id="APP_NAME">%1$s</xliff:g>」"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已更新。請選擇要將哪些存取權限授予這個應用程式。"</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"取消"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"繼續"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"新權限"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"目前權限"</string>
+ <string name="message_staging" msgid="6151794817691100003">"正在啟動應用程式安裝程序…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"不明"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"為了安全起見,你的平板電腦禁止安裝這個來源提供的不明應用程式。"</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"為了安全起見,你的電視禁止安裝這個來源提供的不明應用程式。"</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"為了安全起見,你的手機禁止安裝這個來源提供的不明應用程式。"</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"來歷不明的應用程式可能會損害你的手機和個人資料。如因安裝及使用這個應用程式,導致你的手機受損或資料遺失,請自行負責。"</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"來歷不明的應用程式可能會損害你的平板電腦和個人資料。如因安裝及使用這個應用程式,導致你的平板電腦受損或資料遺失,請自行負責。"</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"來歷不明的應用程式可能會損害你的電視和個人資料。如因安裝及使用這個應用程式,導致你的電視受損或資料遺失,請自行負責。"</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"繼續"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"設定"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"安裝/解除安裝 Wear 應用程式"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zu-television/strings.xml b/packages/PackageInstaller/res/values-zu-television/strings.xml
new file mode 100644
index 0000000..a07ad2e
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zu-television/strings.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5694574989758145558">"Yenqaba futhi ungasabuzi"</string>
+ <string name="grant_dialog_how_to_change" msgid="615414835189256888">"Ungashintsha lokhu kamuva kuzilungiselelo > izinhlelo zokusebenza"</string>
+ <string name="current_permission_template" msgid="4793247012451594523">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7330308025768596149">"Bonisa izinhlelo zokusebenza zesistimu"</string>
+ <string name="app_permissions_decor_title" msgid="1461057434211920209">"Izimvume zohlelo lokusebenza"</string>
+ <string name="manage_permissions_decor_title" msgid="4823785025722958092">"Izimvume zohlelo lokusebenza"</string>
+ <string name="permission_apps_decor_title" msgid="3644363529649579576">"<xliff:g id="PERMISSION">%1$s</xliff:g> izimvume"</string>
+ <string name="additional_permissions_decor_title" msgid="7000432624396037882">"Izimvume ezingeziwe"</string>
+ <string name="system_apps_decor_title" msgid="5292119639812561805">"<xliff:g id="PERMISSION">%1$s</xliff:g> izimvume"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zu-watch/strings.xml b/packages/PackageInstaller/res/values-zu-watch/strings.xml
new file mode 100644
index 0000000..38fe1c8
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zu-watch/strings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="grant_dialog_button_deny_dont_ask_again" msgid="5828565432145544298">"Yenqaba, ungangibuzi futhi"</string>
+ <string name="current_permission_template" msgid="6691830243038105737">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="preference_show_system_apps" msgid="7042886929865431207">"Bonisa izinhlelo zokusebenza zesistimu"</string>
+ <string name="permission_summary_enforced_by_policy" msgid="9002523259681588936">"Akukwazi ukushintshwa"</string>
+ <string name="generic_yes" msgid="3394094077553763689">"Yebo"</string>
+ <string name="generic_cancel" msgid="6384078447202012984">"Khansela"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml
new file mode 100644
index 0000000..6ece479
--- /dev/null
+++ b/packages/PackageInstaller/res/values-zu/strings.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_name" msgid="2738748390251381682">"Isifaki sephakheji"</string>
+ <string name="next" msgid="3057143178373252333">"Okulandelayo"</string>
+ <string name="install" msgid="5896438203900042068">"Faka"</string>
+ <string name="done" msgid="3889387558374211719">"Kwenziwe"</string>
+ <string name="cancel" msgid="8360346460165114585">"Khansela"</string>
+ <string name="installing" msgid="8613631001631998372">"Iyafaka..."</string>
+ <string name="installing_app" msgid="4097935682329028894">"Ifaka i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="install_done" msgid="3682715442154357097">"I-App ifakiwe."</string>
+ <string name="install_confirm_question" msgid="7295206719219043890">"Ngabe ufuna ukufaka lolu hlelo lokusebenza? Lizothola ukufinyelela ku:"</string>
+ <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ngabe ufuna ukufaka lolu hlelo lokusebenza? Alidingi ukufinyelela okukhethekile."</string>
+ <string name="install_confirm_question_update" msgid="4624159567361487964">"Ngabe ufuna ukufaka isibuyekezo ohlelweni lokusebenza olukhona? Idatha yakho ekhona izolahleka. Uhlelo lokusebenza olubuyekeziwe lizothola ukufinyelela ku:"</string>
+ <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ngabe ufuna ukufaka isibuyekezo kulolu hlelo lokusebenza olakhelwe phakathi? Idatha yakho ekhona izolahleka. Uhlelo lokusebenza olubuyekeziwe luzothola ukufinyelela ku:"</string>
+ <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ingabe ufuna ukufaka isibuyekezo kulolu hlelo lokusebenza olukhona? Idatha yakho ekhona ngeke ilahleke. Akudingi ukufinyelela okukhethekile."</string>
+ <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ungabe ufuna ukukhipha isibuyekezo kulolu hlelo lokusebenza olakhelwe ngaphakathi? Idatha yakho ekhona ngeke ilahleke. Akudingi ukufinyelela okukhethekile."</string>
+ <string name="install_failed" msgid="6579998651498970899">"I-app ayifakiwe."</string>
+ <string name="install_failed_blocked" msgid="1606870930588770025">"Iphakheji livinjiwe kusukela ekufakweni."</string>
+ <string name="install_failed_conflict" msgid="5336045235168070954">"Uhlelo lokusebenza alufakiwe njengoba ukuphakheja kushayisana nephakheji elikhona."</string>
+ <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Uhlelo lokusebenza alufakiwe njengoba uhlelo lokusebenza lungahambisani nethebulethi yakho."</string>
+ <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Lolu hlelo lokusebenza aluhambisani ne-TV yakho."</string>
+ <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Uhlelo lokusebenza alufakiwe njengoba uhlelo lokusebenza lungahambisani nefoni yakho."</string>
+ <string name="install_failed_invalid_apk" msgid="269885385245534742">"Uhlelo lokusebenza alufakiwe njengoba iphakheji ibonakala ingavumelekile."</string>
+ <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa kuthebhulethi."</string>
+ <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa ku-TV yakho."</string>
+ <string name="install_failed_msg" product="default" msgid="8554909560982962052">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa efonini."</string>
+ <string name="launch" msgid="4826921505917605463">"Vula"</string>
+ <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Umlawuli wakho akavumeli ukufakwa kwezinhlelo zokusebenza ezitholwe kusukela kumithombo engaziwa"</string>
+ <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Izinhlelo zokusebenza ezingaziwa azikwazi ukufakwa ilo msebenzisi"</string>
+ <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Lo msebenzisi akavunyelwe ukufaka izinhlelo zokusebenza"</string>
+ <string name="ok" msgid="3468756155452870475">"KULUNGILE"</string>
+ <string name="manage_applications" msgid="4033876279091996596">"Phatha izinhlelo zokusebenza"</string>
+ <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Iphelelwe yisikhala"</string>
+ <string name="out_of_space_dlg_text" msgid="4774775404294282216">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa. Khulula isikhala bese uzama futhi."</string>
+ <string name="app_not_found_dlg_title" msgid="2692335460569505484">"I-App ayitholakalanga"</string>
+ <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Uhlelo lokusebenza alutholakalanga ohlwini lwezinhlelo zokusebenza ezifakiwe."</string>
+ <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Akuvumelekile"</string>
+ <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Umsebenzisi wamanje akavunyelwe ukwenza lokhu kukhipha."</string>
+ <string name="generic_error_dlg_title" msgid="2684806600635296961">"Iphutha"</string>
+ <string name="generic_error_dlg_text" msgid="4288738047825333954">"Amafu ohlelo lokusebenza angakhishwa."</string>
+ <string name="uninstall_application_title" msgid="1860074100811653963">"Khipha i-app"</string>
+ <string name="uninstall_update_title" msgid="4146940097553335390">"Khipha isibuyekezo"</string>
+ <string name="uninstall_activity_text" msgid="6680688689803932550">"I-<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ingxenye yohlelo lokusebenza olulandelayo:"</string>
+ <string name="uninstall_application_text" msgid="6691975835951187030">"Ufuna ukukhipha le-app?"</string>
+ <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ingabe ufuna ukukhipha lolu hlelo lokusebenza kubo "<b>"bonke"</b>" abasebenzisi? Uhlelo lokusebenza nedatha yalo kuzosuswa kubo "<b>"bonke"</b>" abasebenzisi kudivayisi."</string>
+ <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ingabe ufuna ukukhiphela lolu hlelo lokusebenza kumsebenzisi ongu-<xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+ <string name="uninstall_update_text" msgid="1394549691152728409">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa."</string>
+ <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa. Lokhu kuthinta bonke abasebenzisi bale divayisi, abafaka labo abanamaphrofayela wokusebenza."</string>
+ <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Ukukhishwa okuqhubekayo"</string>
+ <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ukukhishwa okuhlulekile"</string>
+ <string name="uninstalling" msgid="5556217435895938250">"Iyakhipha..."</string>
+ <string name="uninstalling_app" msgid="2773617614877719294">"Ikhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+ <string name="uninstall_done" msgid="3792487853420281888">"Ukukhipha kuqedile"</string>
+ <string name="uninstall_done_app" msgid="775837862728680479">"Kukhishwe i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_failed" msgid="631122574306299512">"Ukukhipha akuphumelelanga."</string>
+ <string name="uninstall_failed_app" msgid="945277834056527022">"Ukukhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> akuphumelele."</string>
+ <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ayikwazi ukukhipha uhlelo lokusebenza lomlawuli ledivayisi esebenzayo"</string>
+ <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ayikwazi ukukhipha uhlelo lokusebenza lomlawuli ledivayisi esebenzayo lika-<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+ <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Lolu hlelo lokusebenza luyadingeka kwabanye abasebenzisi noma amaphrofayela futhi lukhishelwe abanye"</string>
+ <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Lolu hlelo lokusebenza ludingelwa iphrofayela yakho futhi alikwazi ukukhishwa."</string>
+ <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Lolu hlelo lokusebenza ludingwa umlawuli wedivayisi yakho futhi alukwazi ukukhishwa."</string>
+ <string name="manage_device_administrators" msgid="118178632652346535">"Phatha izinhlelo zokusebenza zedivayisi yomlawuli"</string>
+ <string name="manage_users" msgid="3125018886835668847">"Phatha abasebenzisi"</string>
+ <string name="uninstall_failed_msg" msgid="8969754702803951175">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukukhishwa"</string>
+ <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kube nenkinga yokwehlukanisa iphakheji."</string>
+ <string name="newPerms" msgid="6039428254474104210">"Okusha"</string>
+ <string name="allPerms" msgid="1024385515840703981">"Konke"</string>
+ <string name="privacyPerms" msgid="1850527049572617">"Ubumfihlo"</string>
+ <string name="devicePerms" msgid="6733560207731294504">"Ukufinyelela kwedivayisi"</string>
+ <string name="no_new_perms" msgid="6657813692169565975">"Lesi sibuyekezo asidingi zimvume."</string>
+ <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Phika"</string>
+ <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Olunye ulwazi"</string>
+ <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Yenqaba noma kunjalo"</string>
+ <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> kokungu-<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
+ <string name="permission_warning_template" msgid="7332275268559121742">"Vumela i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ukuthi <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Njalo vumela i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ukwenza <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
+ <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Kuphela ngenkathi usebenzisa uhlelo lokusebenza"</string>
+ <string name="allow_permission_always" msgid="7047379650123289823">"Njalo"</string>
+ <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Yenqaba futhi ungasabuzi"</string>
+ <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> kukhutshaziwe"</string>
+ <string name="permission_revoked_all" msgid="8595742638132863678">"konke kukhutshaziwe"</string>
+ <string name="permission_revoked_none" msgid="2059511550181271342">"Lutho olukhutshaziwe"</string>
+ <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Vumela"</string>
+ <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Izinhlelo zokusebenza"</string>
+ <string name="app_permissions" msgid="3146758905824597178">"Izimvume zohlelo lokusebenza"</string>
+ <string name="never_ask_again" msgid="1089938738199748687">"Ungaphindi ubuze"</string>
+ <string name="no_permissions" msgid="3210542466245591574">"Akukho zimvume"</string>
+ <string name="additional_permissions" msgid="6667573114240111763">"Izimvume ezingeziwe"</string>
+ <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Vula ulwazi lohlelo lokusebenza"</string>
+ <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
+ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okuningi</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okuningi</item>
+ </plurals>
+ <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Lolu hlelo lokusebenza ludizayinelwe inguqulo endala ye-Android. Ukwala imvume kungalibangela ukuthi lingasasebenzi njengoba kuhlosiwe."</string>
+ <string name="default_permission_description" msgid="4992892207044156668">"Yenza isenzo esingaziwa"</string>
+ <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> kuzinhlelo zokusebenza ezingu-<xliff:g id="COUNT_1">%2$d</xliff:g> ezivunyelwe"</string>
+ <string name="menu_show_system" msgid="6773743421743728921">"Bonisa isistimu"</string>
+ <string name="menu_hide_system" msgid="7595471742649432977">"Fihla isistimu"</string>
+ <string name="no_apps" msgid="1965493419005012569">"Azikho izinhlelo zokusebenza"</string>
+ <string name="location_settings" msgid="1774875730854491297">"Izilungiselelo Zendawo"</string>
+ <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ingumhlinzeki wamasevisi wendawo kule divayisi. Ukufinyelela kwendawo kungashintshwa kusuka kuzilungiselelo zendawo."</string>
+ <string name="system_warning" msgid="7103819124542305179">"Uma unqabela le mvume, izici eziyisisekelo zedivayisi yakho zingahle zingasasebenzi njengoba zihlosiwe."</string>
+ <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Isetshenziswe yinqubomgomo"</string>
+ <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Ukufinyelela kwangemuva kukhutshazwe inqubomgomo"</string>
+ <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Ukufinyelela kwangemuva kunikwe amandla ngenqubomgomo"</string>
+ <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ukufinyelela kwangaphambili kunikwe amandla ngenqubomgomo"</string>
+ <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kulawulwa umqondisi"</string>
+ <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
+ <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
+ <string name="permission_access_always" msgid="5642491469836594184">"Njalo"</string>
+ <string name="permission_access_only_foreground" msgid="6906814759741316041">"Kuphela ngenkathi usebenzisa uhlelo lokusebenza"</string>
+ <string name="permission_access_never" msgid="1258330706341318622">"Soze"</string>
+ <string name="loading" msgid="7811651799620593731">"Iyalayisha..."</string>
+ <string name="all_permissions" msgid="5156669007784613042">"Zonke izimvume"</string>
+ <string name="other_permissions" msgid="2016192512386091933">"Amanye amakhono wohlelo lokusebenza"</string>
+ <string name="permission_request_title" msgid="1204446718549121199">"Isicelo semvume"</string>
+ <string name="screen_overlay_title" msgid="3021729846864038529">"Kutholwe imbondela yesikrini"</string>
+ <string name="screen_overlay_message" msgid="2141944461571677331">"Ukuze uguqule lesi silungiselelo semvume, kuzomele uqale uvale imbondela yesikrini kusukela ku-Izilungiselelo > Izinhlelo zokusebenza"</string>
+ <string name="screen_overlay_button" msgid="4344544843349937743">"Vula izilungiselelo"</string>
+ <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"I-Android Wear"</string>
+ <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Izenzo zokufaka/ukukhipha azisekelwe ku-Wear."</string>
+ <string name="permission_review_title_template_install" msgid="6819338441305295479">"Khetha ukuthi uzovumela ini ukuthi i-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ifinyelele kuyo"</string>
+ <string name="permission_review_title_template_update" msgid="8632233603161669426">"I-<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ibuyekeziwe. Khetha ukuthi uzovumela ini ukuthi ifinyelelwe ilolu hlelo lokusebenza."</string>
+ <string name="review_button_cancel" msgid="957906817733578877">"Khansela"</string>
+ <string name="review_button_continue" msgid="4809162078179371370">"Qhubeka"</string>
+ <string name="new_permissions_category" msgid="3213523410139204183">"Izimvume ezintsha"</string>
+ <string name="current_permissions_category" msgid="998210994450606094">"Izimvume zamanje"</string>
+ <string name="message_staging" msgid="6151794817691100003">"Ifaka kusiteji uhlelo lokusebenza…"</string>
+ <string name="app_name_unknown" msgid="8931522764510159105">"Akwaziwa"</string>
+ <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Ukuze uvikelwe, ithebulethi yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza ezingaziwa kusukela kulo mthombo."</string>
+ <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Ukuze uvikelwe, i-TV yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza ezingaziwa kusukela kulo mthombo."</string>
+ <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Ukuze uvikelwe, ifoni yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza kusukela kulo mthombo."</string>
+ <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Idatha yakho yefoni neyohlelo lwakho lokusebenza isengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala kufoni yakho noma ukulahlekelwa kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
+ <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ithebulethi yakho nedatha yomuntu siqu zisengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala kuthebulethi yakho noma ukulahleka kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
+ <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Idatha yakho ye-TV neyomuntu siqu isengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala ku-TV yakho noma ukulahlekelwa kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
+ <string name="anonymous_source_continue" msgid="2094381167954332292">"Qhubeka"</string>
+ <string name="external_sources_settings" msgid="8601453744517291632">"Izilungiselelo"</string>
+ <string name="wear_app_channel" msgid="6200840123672949356">"Ifaka/ikhipha izinhlelo zokusebenza ze-wear"</string>
+</resources>
diff --git a/packages/PackageInstaller/res/values/attrs.xml b/packages/PackageInstaller/res/values/attrs.xml
new file mode 100644
index 0000000..e220f4c
--- /dev/null
+++ b/packages/PackageInstaller/res/values/attrs.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- START: Ported from WearableSupport -->
+ <declare-styleable name="CircledImageView">
+ <attr name="android:src" />
+ <attr name="circle_color" format="color" />
+ <attr name="circle_radius" format="dimension" />
+ <attr name="circle_radius_pressed" format="dimension" />
+ <attr name="circle_border_width" format="dimension" />
+ <attr name="circle_border_color" format="color" />
+ <attr name="circle_padding" format="dimension" />
+ <attr name="shadow_width" format="dimension" />
+ <attr name="image_circle_percentage" format="dimension" />
+ <attr name="image_horizontal_offcenter_percentage" format="dimension" />
+ <attr name="image_tint" format="color" />
+ <attr name="circle_radius_percent" format="fraction" />
+ <attr name="circle_radius_pressed_percent" format="fraction" />
+ </declare-styleable>
+ <!-- END: Ported from WearableSupport -->
+</resources>
diff --git a/packages/PackageInstaller/res/values/colors.xml b/packages/PackageInstaller/res/values/colors.xml
new file mode 100644
index 0000000..01a0c9a
--- /dev/null
+++ b/packages/PackageInstaller/res/values/colors.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<resources>
+ <color name="bigIconColor">#C8CCCE</color>
+</resources>
diff --git a/packages/PackageInstaller/res/values/dimens.xml b/packages/PackageInstaller/res/values/dimens.xml
new file mode 100644
index 0000000..112723f
--- /dev/null
+++ b/packages/PackageInstaller/res/values/dimens.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources>
+ <!-- Header sub settings margin start / end -->
+ <dimen name="header_subsettings_margin_start">72dp</dimen>
+ <dimen name="header_subsettings_margin_end">16dp</dimen>
+
+ <!-- Header margin start / end -->
+ <dimen name="header_margin_start">16dp</dimen>
+ <dimen name="header_margin_end">16dp</dimen>
+
+ <dimen name="lb_action_section_width">384dp</dimen>
+
+ <dimen name="lb_content_section_width">576dp</dimen>
+ <dimen name="lb_content_fragment_start_padding">48dp</dimen>
+ <dimen name="lb_content_fragment_delimiter_padding">16dp</dimen>
+ <dimen name="lb_content_fragment_max_icon_height">280dp</dimen>
+ <dimen name="lb_content_fragment_title_text_top_padding">2dp</dimen>
+ <dimen name="lb_content_fragment_title_text_size">36sp</dimen>
+ <dimen name="lb_content_fragment_icon_width">140dp</dimen>
+
+ <dimen name="lb_content_fragment_breadcrumb_text_size">18sp</dimen>
+ <dimen name="lb_content_fragment_description_text_size">14sp</dimen>
+ <dimen name="lb_content_fragment_title_text_bottom_padding">4dp</dimen>
+
+ <dimen name="headerElevation">8dp</dimen>
+
+ <dimen name="wear_permission_review_pref_padding">8dp</dimen>
+ <dimen name="wear_permission_review_icon_size">24dp</dimen>
+</resources>
diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml
new file mode 100644
index 0000000..6c7160f
--- /dev/null
+++ b/packages/PackageInstaller/res/values/strings.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- [CHAR LIMIT=25] -->
+ <string name="app_name">Package installer</string>
+
+ <!-- [CHAR LIMIT=15] -->
+ <string name="install">Install</string>
+ <!-- [CHAR LIMIT=15] -->
+ <string name="done">Done</string>
+ <!-- [CHAR LIMIT=15] -->
+ <string name="cancel">Cancel</string>
+ <!-- [CHAR LIMIT=50] -->
+ <string name="installing">Installing\u2026</string>
+ <!-- [CHAR LIMIT=50] -->
+ <string name="installing_app">Installing <xliff:g id="package_label">%1$s</xliff:g>\u2026</string>
+ <!-- [CHAR LIMIT=100] -->
+ <string name="install_done">App installed.</string>
+ <!-- Message for installing a new app that requires some permissions [CHAR LIMIT=NONE] -->
+ <!-- Message for installing a new app that does not require permissions [CHAR LIMIT=NONE] -->
+ <string name="install_confirm_question">Do you want to install this application?</string>
+ <!-- Message for updating an existing app [CHAR LIMIT=NONE] -->
+ <string name="install_confirm_question_update">Do you want to install an update
+ to this existing application? Your existing data will not
+ be lost. The updated application will get access to:</string>
+ <!-- Message for updating an existing system app [CHAR LIMIT=NONE] -->
+ <string name="install_confirm_question_update_system">Do you want to install an update
+ to this built-in application? Your existing data will not
+ be lost. The updated application will get access to:</string>
+ <!-- [CHAR LIMIT=100] -->
+ <string name="install_failed">App not installed.</string>
+ <!-- Reason displayed when installation fails because the package was blocked
+ from being installed (e.g., device policy, verification, ...) [CHAR LIMIT=100] -->
+ <string name="install_failed_blocked">The package was blocked from being installed.</string>
+ <!-- Reason displayed when installation fails because the package conflicts with
+ an existing application (e.g., incompatible certificates) [CHAR LIMIT=100] -->
+ <string name="install_failed_conflict">App not installed as package conflicts with an existing package.</string>
+ <!-- Reason displayed when installation fails because the package is incompatible with
+ the current tablet (e.g., missing native code for the current ABI, newer SDK, ...) [CHAR LIMIT=100] -->
+ <string name="install_failed_incompatible" product="tablet">App not installed as app isn\'t
+ compatible with your tablet.</string>
+ <!-- Reason displayed when installation fails because the package is incompatible with
+ the current TV (e.g., missing native code for the current ABI, newer SDK, ...) [CHAR LIMIT=100] -->
+ <string name="install_failed_incompatible" product="tv">This app isn\'t
+ compatible with your TV.</string>
+ <!-- Reason displayed when installation fails because the package is incompatible with
+ the current phone (e.g., missing native code for the current ABI, newer SDK, ...) [CHAR LIMIT=100] -->
+ <string name="install_failed_incompatible" product="default">App not installed as app isn\'t
+ compatible with your phone.</string>
+ <!-- Reason displayed when installation fails because the installation package itself is invalid
+ in some way (e.g., corrupt) [CHAR LIMIT=100] -->
+ <string name="install_failed_invalid_apk">App not installed as package appears to be invalid.</string>
+ <!-- Message presented when an application could not be installed on the tablet for some reason. [CHAR LIMIT=100] -->
+ <string name="install_failed_msg" product="tablet"><xliff:g id="app_name">%1$s</xliff:g> couldn\'t be installed on your tablet.</string>
+ <!-- Message presented when an application could not be installed on the TV for some reason. [CHAR LIMIT=100] -->
+ <string name="install_failed_msg" product="tv"><xliff:g id="app_name">%1$s</xliff:g> couldn\'t be installed on your TV.</string>
+ <!-- Message presented when an application could not be installed on the phone for some reason. [CHAR LIMIT=100] -->
+ <string name="install_failed_msg" product="default"><xliff:g id="app_name">%1$s</xliff:g> couldn\'t be installed on your phone.</string>
+ <string name="launch">Open</string>
+
+ <!-- Message presented in a dialog box when the device administrator restricts the installation of apps from unknown sources. [CHAR LIMIT=none] -->
+ <string name="unknown_apps_admin_dlg_text">Your admin doesn\'t allow installation of apps
+ obtained from unknown sources</string>
+ <!-- Message presented in a dialog box when the user restriction set by the system restricts the installation of apps from unknown sources. [CHAR LIMIT=none] -->
+ <string name="unknown_apps_user_restriction_dlg_text">Unknown apps can\'t be installed by this
+ user</string>
+ <!-- Message presented in a dialog box when the user restriction set by the system restricts the installation of apps. [CHAR LIMIT=none] -->
+ <string name="install_apps_user_restriction_dlg_text">This user is not allowed to install apps</string>
+
+ <!-- [CHAR LIMIT=15] -->
+ <string name="ok">OK</string>
+ <!-- [CHAR LIMIT=15] -->
+ <string name="manage_applications">Manage apps</string>
+ <!-- [CHAR LIMIT=30] -->
+ <string name="out_of_space_dlg_title">Out of space</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="out_of_space_dlg_text"><xliff:g id="app_name">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again.</string>
+ <!-- strings related to uninstall activity -->
+ <!-- [CHAR LIMIT=30] -->
+ <string name="app_not_found_dlg_title">App not found</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="app_not_found_dlg_text"> The app wasn\'t found in the list of installed apps.</string>
+ <!-- [CHAR LIMIT=30] -->
+ <string name="user_is_not_allowed_dlg_title">Not allowed</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="user_is_not_allowed_dlg_text">The current user is not allowed to perform this uninstallation.</string>
+ <!-- [CHAR LIMIT=30] -->
+ <string name="generic_error_dlg_title">Error</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="generic_error_dlg_text">App could not be uninstalled.</string>
+ <!-- [CHAR LIMIT=30] -->
+ <string name="uninstall_application_title">Uninstall app</string>
+ <!-- [CHAR LIMIT=30] -->
+ <string name="uninstall_update_title">Uninstall update</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="uninstall_activity_text"><xliff:g id="activity_name">%1$s</xliff:g> is part of the following app:</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="uninstall_application_text">Do you want to uninstall this app?</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="uninstall_application_text_all_users">Do you want to uninstall this app for <b>all</b>
+ users? The application and its data will be removed from <b>all</b> users on the device.</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="uninstall_application_text_user">Do you want to uninstall this app for the user <xliff:g id="username">%1$s</xliff:g>?</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="uninstall_update_text">Replace this app with the factory version? All data will be removed.</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="uninstall_update_text_multiuser">Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles.</string>
+
+ <!-- Label for the notification channel containing notifications for current uninstall operations [CHAR LIMIT=40] -->
+ <string name="uninstalling_notification_channel">Running uninstalls</string>
+ <!-- Label for the notification channel containing notifications for failed uninstall operations [CHAR LIMIT=40] -->
+ <string name="uninstall_failure_notification_channel">Failed uninstalls</string>
+
+ <!-- [CHAR LIMIT=50] -->
+ <string name="uninstalling">Uninstalling\u2026</string>
+ <!-- [CHAR LIMIT=50] -->
+ <string name="uninstalling_app">Uninstalling <xliff:g id="package_label">%1$s</xliff:g>\u2026</string>
+ <!-- [CHAR LIMIT=100] -->
+ <string name="uninstall_done">Uninstall finished.</string>
+ <!-- [CHAR LIMIT=100] -->
+ <string name="uninstall_done_app">Uninstalled <xliff:g id="package_label">%1$s</xliff:g></string>
+ <!-- [CHAR LIMIT=100] -->
+ <string name="uninstall_failed">Uninstall unsuccessful.</string>
+ <!-- [CHAR LIMIT=100] -->
+ <string name="uninstall_failed_app">Uninstalling <xliff:g id="package_label">%1$s</xliff:g> unsuccessful.</string>
+ <!-- String presented to the user when uninstalling a package failed because the target package
+ is a current device administrator [CHAR LIMIT=80] -->
+ <string name="uninstall_failed_device_policy_manager">Can\'t uninstall active device admin
+ app</string>
+ <!-- String presented to the user when uninstalling a package failed because the target package
+ is a current device administrator for some user [CHAR LIMIT=100] -->
+ <string name="uninstall_failed_device_policy_manager_of_user">Can\'t uninstall active device
+ admin app for <xliff:g id="username">%1$s</xliff:g></string>
+ <!-- String presented to the admin user when uninstalling a package for all users failed
+ because a profile owner has marked the target package as not able to be uninstalled
+ [CHAR LIMIT=120] -->
+ <string name="uninstall_all_blocked_profile_owner">This app is required for some users or
+ profiles and was uninstalled for others</string>
+ <!-- String presented to the user when uninstalling a package failed because a profile owner
+ has marked the target package as not able to be uninstalled [CHAR LIMIT=120] -->
+ <string name="uninstall_blocked_profile_owner">This app is needed for
+ your profile and can\'t be uninstalled.</string>
+ <!-- String presented to the user when uninstalling a package failed because a device owner
+ has marked the the target package as not able to be uninstalled [CHAR LIMIT=80] -->
+ <string name="uninstall_blocked_device_owner">This app is required
+ by your device administrator and can\'t be uninstalled.</string>
+ <!-- String on a button that leads to the "device admin apps" configuration setting where a
+ user will be able to disable the device admin app in order to uninstall
+ it. [CHAR LIMIT=50] -->
+ <string name="manage_device_administrators">Manage device admin apps</string>
+ <!-- String on a button that leads to the "Users" page in Settings where a
+ user will be able to remove the secondary user(s) in order to uninstall
+ the app. [CHAR LIMIT=50] -->
+ <string name="manage_users">Manage users</string>
+ <!-- [CHAR LIMIT=none] -->
+ <string name="uninstall_failed_msg"><xliff:g id="app_name">%1$s</xliff:g> couldn\'t be uninstalled.</string>
+
+ <!-- Dialog attributes to indicate parse errors -->
+ <string name="Parse_error_dlg_text">There was a problem parsing the package.</string>
+
+ <!-- Title of dialog telling users that Install/Uninstall action is not supported on Android Wear. [CHAR LIMIT=30] -->
+ <string name="wear_not_allowed_dlg_title">Android Wear</string>
+ <!-- Title of dialog telling users that Install/Uninstall action is not supported on Android Wear. [CHAR LIMIT=none] -->
+ <string name="wear_not_allowed_dlg_text">Install/Uninstall actions not supported on Wear.</string>
+
+ <!-- Message that the app to be installed is being staged [CHAR LIMIT=50] -->
+ <string name="message_staging">Staging app…</string>
+
+ <!-- Placeholder for an app name when it is unknown [CHAR LIMIT=50] -->
+ <string name="app_name_unknown">Unknown</string>
+
+ <!-- Help URL, application permissions [DO NOT TRANSLATE] -->
+ <string name="help_app_permissions" translatable="false"></string>
+
+ <!-- Text to show in warning dialog on the tablet when the app source is not trusted [CHAR LIMIT=NONE] -->
+ <string name="untrusted_external_source_warning" product="tablet">For your security, your tablet is not allowed to install unknown apps from this source.</string>
+
+ <!-- Text to show in warning dialog on the tv when the app source is not trusted [CHAR LIMIT=NONE] -->
+ <string name="untrusted_external_source_warning" product="tv">For your security, your TV is not allowed to install unknown apps from this source.</string>
+
+ <!-- Text to show in warning dialog on the phone when the app source is not trusted [CHAR LIMIT=NONE] -->
+ <string name="untrusted_external_source_warning" product="default">For your security, your phone is not allowed to install unknown apps from this source.</string>
+
+ <!-- Text to show in warning dialog on the phone when the app source cannot be identified [CHAR LIMIT=NONE] -->
+ <string name="anonymous_source_warning" product="default">
+ Your phone and personal data are more vulnerable
+ to attack by unknown apps. By installing this app, you
+ agree that you are responsible for any damage to your
+ phone or loss of data that may result from its use.
+ </string>
+
+ <!-- Text to show in warning dialog on the tablet when the app source cannot be identified [CHAR LIMIT=NONE] -->
+ <string name="anonymous_source_warning" product="tablet">
+ Your tablet and personal data are more vulnerable
+ to attack by unknown apps. By installing this app, you
+ agree that you are responsible for any damage to your
+ tablet or loss of data that may result from its use.
+ </string>
+
+ <!-- Text to show in warning dialog on the tv when the app source cannot be identified [CHAR LIMIT=NONE] -->
+ <string name="anonymous_source_warning" product="tv">
+ Your TV and personal data are more vulnerable
+ to attack by unknown apps. By installing this app, you
+ agree that you are responsible for any damage to your
+ TV or loss of data that may result from its use.
+ </string>
+
+ <!-- Label for button to continue install of an app whose source cannot be identified [CHAR LIMIT=40] -->
+ <string name="anonymous_source_continue">Continue</string>
+
+ <!-- Label for button to open manage external sources settings [CHAR LIMIT=45] -->
+ <string name="external_sources_settings">Settings</string>
+
+ <!-- Label for the notification channel containing notifications for embedded app operations [CHAR LIMIT=40] -->
+ <string name="wear_app_channel">Installing/uninstalling wear apps</string>
+
+</resources>
diff --git a/packages/PackageInstaller/res/values/styles.xml b/packages/PackageInstaller/res/values/styles.xml
new file mode 100755
index 0000000..f79f98f
--- /dev/null
+++ b/packages/PackageInstaller/res/values/styles.xml
@@ -0,0 +1,39 @@
+<?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>
+
+ <style name="MediumText"
+ parent="@android:style/TextAppearance.Medium">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="SmallText"
+ parent="@android:style/TextAppearance.Small">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="TitleText">
+ <item name="android:fontFamily">sans-serif-medium</item>
+ <item name="android:textSize">20dp</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ </style>
+
+ <style name="ActionBar" parent="@android:style/Widget.Material.ActionBar.Solid">
+ <item name="android:contentInsetStart">72dp</item>
+ </style>
+
+</resources>
diff --git a/packages/PackageInstaller/res/values/themes.xml b/packages/PackageInstaller/res/values/themes.xml
new file mode 100644
index 0000000..6df6246
--- /dev/null
+++ b/packages/PackageInstaller/res/values/themes.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2015 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<resources>
+
+ <style name="DialogWhenLarge"
+ parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
+ <item name="android:textAppearanceMedium">@style/MediumText</item>
+ <item name="android:textAppearanceSmall">@style/SmallText</item>
+ <item name="android:titleTextStyle">@style/TitleText</item>
+ </style>
+
+ <style name="DialogWhenLargeNoAnimation" parent="DialogWhenLarge">
+ <item name="android:windowAnimationStyle">@null</item>
+ </style>
+
+ <style name="AlertDialogActivity"
+ parent="@android:style/Theme.DeviceDefault.Light.Panel">
+ <item name="android:backgroundDimEnabled">true</item>
+ </style>
+
+ <style name="Header.Settings"
+ parent="@android:style/Theme.DeviceDefault.Settings">
+ </style>
+
+
+</resources>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
new file mode 100644
index 0000000..399cf1f
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.annotation.Nullable;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import java.io.File;
+
+/**
+ * Trampoline activity. Calls PackageInstallerActivity and deletes staged install file onResult.
+ */
+public class DeleteStagedFileOnResult extends Activity {
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (savedInstanceState == null) {
+ Intent installIntent = new Intent(getIntent());
+ installIntent.setClass(this, PackageInstallerActivity.class);
+
+ installIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ startActivityForResult(installIntent, 0);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ File sourceFile = new File(getIntent().getData().getPath());
+ sourceFile.delete();
+
+ setResult(resultCode, data);
+ finish();
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/DeviceUtils.java b/packages/PackageInstaller/src/com/android/packageinstaller/DeviceUtils.java
new file mode 100644
index 0000000..b54cad6
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/DeviceUtils.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
+
+public class DeviceUtils {
+ public static boolean isTelevision(Context context) {
+ int uiMode = context.getResources().getConfiguration().uiMode;
+ return (uiMode & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION;
+ }
+
+ public static boolean isWear(final Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH);
+ }
+
+ public static boolean isAuto(Context context) {
+ return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/EventResultPersister.java b/packages/PackageInstaller/src/com/android/packageinstaller/EventResultPersister.java
new file mode 100644
index 0000000..0e62889
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/EventResultPersister.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInstaller;
+import android.os.AsyncTask;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.util.AtomicFile;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * Persists results of events and calls back observers when a matching result arrives.
+ */
+class EventResultPersister {
+ private static final String LOG_TAG = EventResultPersister.class.getSimpleName();
+
+ /** Id passed to {@link #addObserver(int, EventResultObserver)} to generate new id */
+ static final int GENERATE_NEW_ID = Integer.MIN_VALUE;
+
+ /**
+ * The extra with the id to set in the intent delivered to
+ * {@link #onEventReceived(Context, Intent)}
+ */
+ static final String EXTRA_ID = "EventResultPersister.EXTRA_ID";
+
+ /** Persisted state of this object */
+ private final AtomicFile mResultsFile;
+
+ private final Object mLock = new Object();
+
+ /** Currently stored but not yet called back results (install id -> status, status message) */
+ private final SparseArray<EventResult> mResults = new SparseArray<>();
+
+ /** Currently registered, not called back observers (install id -> observer) */
+ private final SparseArray<EventResultObserver> mObservers = new SparseArray<>();
+
+ /** Always increasing counter for install event ids */
+ private int mCounter;
+
+ /** If a write that will persist the state is scheduled */
+ private boolean mIsPersistScheduled;
+
+ /** If the state was changed while the data was being persisted */
+ private boolean mIsPersistingStateValid;
+
+ /**
+ * @return a new event id.
+ */
+ public int getNewId() throws OutOfIdsException {
+ synchronized (mLock) {
+ if (mCounter == Integer.MAX_VALUE) {
+ throw new OutOfIdsException();
+ }
+
+ mCounter++;
+ writeState();
+
+ return mCounter - 1;
+ }
+ }
+
+ /** Call back when a result is received. Observer is removed when onResult it called. */
+ interface EventResultObserver {
+ void onResult(int status, int legacyStatus, @Nullable String message);
+ }
+
+ /**
+ * Progress parser to the next element.
+ *
+ * @param parser The parser to progress
+ */
+ private static void nextElement(@NonNull XmlPullParser parser)
+ throws XmlPullParserException, IOException {
+ int type;
+ do {
+ type = parser.next();
+ } while (type != XmlPullParser.START_TAG && type != XmlPullParser.END_DOCUMENT);
+ }
+
+ /**
+ * Read an int attribute from the current element
+ *
+ * @param parser The parser to read from
+ * @param name The attribute name to read
+ *
+ * @return The value of the attribute
+ */
+ private static int readIntAttribute(@NonNull XmlPullParser parser, @NonNull String name) {
+ return Integer.parseInt(parser.getAttributeValue(null, name));
+ }
+
+ /**
+ * Read an String attribute from the current element
+ *
+ * @param parser The parser to read from
+ * @param name The attribute name to read
+ *
+ * @return The value of the attribute or null if the attribute is not set
+ */
+ private static String readStringAttribute(@NonNull XmlPullParser parser, @NonNull String name) {
+ return parser.getAttributeValue(null, name);
+ }
+
+ /**
+ * Read persisted state.
+ *
+ * @param resultFile The file the results are persisted in
+ */
+ EventResultPersister(@NonNull File resultFile) {
+ mResultsFile = new AtomicFile(resultFile);
+ mCounter = GENERATE_NEW_ID + 1;
+
+ try (FileInputStream stream = mResultsFile.openRead()) {
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(stream, StandardCharsets.UTF_8.name());
+
+ nextElement(parser);
+ while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
+ String tagName = parser.getName();
+ if ("results".equals(tagName)) {
+ mCounter = readIntAttribute(parser, "counter");
+ } else if ("result".equals(tagName)) {
+ int id = readIntAttribute(parser, "id");
+ int status = readIntAttribute(parser, "status");
+ int legacyStatus = readIntAttribute(parser, "legacyStatus");
+ String statusMessage = readStringAttribute(parser, "statusMessage");
+
+ if (mResults.get(id) != null) {
+ throw new Exception("id " + id + " has two results");
+ }
+
+ mResults.put(id, new EventResult(status, legacyStatus, statusMessage));
+ } else {
+ throw new Exception("unexpected tag");
+ }
+
+ nextElement(parser);
+ }
+ } catch (Exception e) {
+ mResults.clear();
+ writeState();
+ }
+ }
+
+ /**
+ * Add a result. If the result is an pending user action, execute the pending user action
+ * directly and do not queue a result.
+ *
+ * @param context The context the event was received in
+ * @param intent The intent the activity received
+ */
+ void onEventReceived(@NonNull Context context, @NonNull Intent intent) {
+ int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 0);
+
+ if (status == PackageInstaller.STATUS_PENDING_USER_ACTION) {
+ context.startActivity(intent.getParcelableExtra(Intent.EXTRA_INTENT));
+
+ return;
+ }
+
+ int id = intent.getIntExtra(EXTRA_ID, 0);
+ String statusMessage = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
+ int legacyStatus = intent.getIntExtra(PackageInstaller.EXTRA_LEGACY_STATUS, 0);
+
+ EventResultObserver observerToCall = null;
+ synchronized (mLock) {
+ int numObservers = mObservers.size();
+ for (int i = 0; i < numObservers; i++) {
+ if (mObservers.keyAt(i) == id) {
+ observerToCall = mObservers.valueAt(i);
+ mObservers.removeAt(i);
+
+ break;
+ }
+ }
+
+ if (observerToCall != null) {
+ observerToCall.onResult(status, legacyStatus, statusMessage);
+ } else {
+ mResults.put(id, new EventResult(status, legacyStatus, statusMessage));
+ writeState();
+ }
+ }
+ }
+
+ /**
+ * Persist current state. The persistence might be delayed.
+ */
+ private void writeState() {
+ synchronized (mLock) {
+ mIsPersistingStateValid = false;
+
+ if (!mIsPersistScheduled) {
+ mIsPersistScheduled = true;
+
+ AsyncTask.execute(() -> {
+ int counter;
+ SparseArray<EventResult> results;
+
+ while (true) {
+ // Take snapshot of state
+ synchronized (mLock) {
+ counter = mCounter;
+ results = mResults.clone();
+ mIsPersistingStateValid = true;
+ }
+
+ FileOutputStream stream = null;
+ try {
+ stream = mResultsFile.startWrite();
+ XmlSerializer serializer = Xml.newSerializer();
+ serializer.setOutput(stream, StandardCharsets.UTF_8.name());
+ serializer.startDocument(null, true);
+ serializer.setFeature(
+ "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+ serializer.startTag(null, "results");
+ serializer.attribute(null, "counter", Integer.toString(counter));
+
+ int numResults = results.size();
+ for (int i = 0; i < numResults; i++) {
+ serializer.startTag(null, "result");
+ serializer.attribute(null, "id",
+ Integer.toString(results.keyAt(i)));
+ serializer.attribute(null, "status",
+ Integer.toString(results.valueAt(i).status));
+ serializer.attribute(null, "legacyStatus",
+ Integer.toString(results.valueAt(i).legacyStatus));
+ if (results.valueAt(i).message != null) {
+ serializer.attribute(null, "statusMessage",
+ results.valueAt(i).message);
+ }
+ serializer.endTag(null, "result");
+ }
+
+ serializer.endTag(null, "results");
+ serializer.endDocument();
+
+ mResultsFile.finishWrite(stream);
+ } catch (IOException e) {
+ if (stream != null) {
+ mResultsFile.failWrite(stream);
+ }
+
+ Log.e(LOG_TAG, "error writing results", e);
+ mResultsFile.delete();
+ }
+
+ // Check if there was changed state since we persisted. If so, we need to
+ // persist again.
+ synchronized (mLock) {
+ if (mIsPersistingStateValid) {
+ mIsPersistScheduled = false;
+ break;
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Add an observer. If there is already an event for this id, call back inside of this call.
+ *
+ * @param id The id the observer is for or {@code GENERATE_NEW_ID} to generate a new one.
+ * @param observer The observer to call back.
+ *
+ * @return The id for this event
+ */
+ int addObserver(int id, @NonNull EventResultObserver observer)
+ throws OutOfIdsException {
+ synchronized (mLock) {
+ int resultIndex = -1;
+
+ if (id == GENERATE_NEW_ID) {
+ id = getNewId();
+ } else {
+ resultIndex = mResults.indexOfKey(id);
+ }
+
+ // Check if we can instantly call back
+ if (resultIndex >= 0) {
+ EventResult result = mResults.valueAt(resultIndex);
+
+ observer.onResult(result.status, result.legacyStatus, result.message);
+ mResults.removeAt(resultIndex);
+ writeState();
+ } else {
+ mObservers.put(id, observer);
+ }
+ }
+
+
+ return id;
+ }
+
+ /**
+ * Remove a observer.
+ *
+ * @param id The id the observer was added for
+ */
+ void removeObserver(int id) {
+ synchronized (mLock) {
+ mObservers.delete(id);
+ }
+ }
+
+ /**
+ * The status from an event.
+ */
+ private class EventResult {
+ public final int status;
+ public final int legacyStatus;
+ @Nullable public final String message;
+
+ private EventResult(int status, int legacyStatus, @Nullable String message) {
+ this.status = status;
+ this.legacyStatus = legacyStatus;
+ this.message = message;
+ }
+ }
+
+ class OutOfIdsException extends Exception {}
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallEventReceiver.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallEventReceiver.java
new file mode 100644
index 0000000..b7d32e9
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallEventReceiver.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import androidx.annotation.NonNull;
+
+/**
+ * Receives install events and perists them using a {@link EventResultPersister}.
+ */
+public class InstallEventReceiver extends BroadcastReceiver {
+ private static final Object sLock = new Object();
+ private static EventResultPersister sReceiver;
+
+ /**
+ * Get the event receiver persisting the results
+ *
+ * @return The event receiver.
+ */
+ @NonNull private static EventResultPersister getReceiver(@NonNull Context context) {
+ synchronized (sLock) {
+ if (sReceiver == null) {
+ sReceiver = new EventResultPersister(
+ TemporaryFileManager.getInstallStateFile(context));
+ }
+ }
+
+ return sReceiver;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ getReceiver(context).onEventReceived(context, intent);
+ }
+
+ /**
+ * Add an observer. If there is already an event for this id, call back inside of this call.
+ *
+ * @param context A context of the current app
+ * @param id The id the observer is for or {@code GENERATE_NEW_ID} to generate a new one.
+ * @param observer The observer to call back.
+ *
+ * @return The id for this event
+ */
+ static int addObserver(@NonNull Context context, int id,
+ @NonNull EventResultPersister.EventResultObserver observer)
+ throws EventResultPersister.OutOfIdsException {
+ return getReceiver(context).addObserver(id, observer);
+ }
+
+ /**
+ * Remove a observer.
+ *
+ * @param context A context of the current app
+ * @param id The id the observer was added for
+ */
+ static void removeObserver(@NonNull Context context, int id) {
+ getReceiver(context).removeObserver(id);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java
new file mode 100644
index 0000000..56dc71d
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallFailed.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import androidx.annotation.Nullable;
+import android.util.Log;
+import android.widget.TextView;
+
+import java.io.File;
+
+/**
+ * Installation failed: Return status code to the caller or display failure UI to user
+ */
+public class InstallFailed extends Activity {
+ private static final String LOG_TAG = InstallFailed.class.getSimpleName();
+
+ /** Label of the app that failed to install */
+ private CharSequence mLabel;
+
+ /**
+ * Convert an package installer status code into the user friendly label.
+ *
+ * @param statusCode The status code from the package installer.
+ *
+ * @return The user friendly label for the status code
+ */
+ private int getExplanationFromErrorCode(int statusCode) {
+ Log.d(LOG_TAG, "Installation status code: " + statusCode);
+
+ switch (statusCode) {
+ case PackageInstaller.STATUS_FAILURE_BLOCKED:
+ return R.string.install_failed_blocked;
+ case PackageInstaller.STATUS_FAILURE_CONFLICT:
+ return R.string.install_failed_conflict;
+ case PackageInstaller.STATUS_FAILURE_INCOMPATIBLE:
+ return R.string.install_failed_incompatible;
+ case PackageInstaller.STATUS_FAILURE_INVALID:
+ return R.string.install_failed_invalid_apk;
+ default:
+ return R.string.install_failed;
+ }
+ }
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ int statusCode = getIntent().getIntExtra(PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE);
+
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ int legacyStatus = getIntent().getIntExtra(PackageInstaller.EXTRA_LEGACY_STATUS,
+ PackageManager.INSTALL_FAILED_INTERNAL_ERROR);
+
+ // Return result if requested
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, legacyStatus);
+ setResult(Activity.RESULT_FIRST_USER, result);
+ finish();
+ } else {
+ Intent intent = getIntent();
+ ApplicationInfo appInfo = intent
+ .getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
+ Uri packageURI = intent.getData();
+
+ setContentView(R.layout.install_failed);
+
+ // Set header icon and title
+ PackageUtil.AppSnippet as;
+ PackageManager pm = getPackageManager();
+
+ if ("package".equals(packageURI.getScheme())) {
+ as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo),
+ pm.getApplicationIcon(appInfo));
+ } else {
+ final File sourceFile = new File(packageURI.getPath());
+ as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
+ }
+
+ // Store label for dialog
+ mLabel = as.label;
+
+ PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
+
+ // Show out of space dialog if needed
+ if (statusCode == PackageInstaller.STATUS_FAILURE_STORAGE) {
+ (new OutOfSpaceDialog()).show(getFragmentManager(), "outofspace");
+ }
+
+ // Get status messages
+ ((TextView) findViewById(R.id.simple_status)).setText(
+ getExplanationFromErrorCode(statusCode));
+
+ // Set up "done" button
+ findViewById(R.id.done_button).setOnClickListener(view -> finish());
+ }
+ }
+
+ /**
+ * Dialog shown when we ran out of space during installation. This contains a link to the
+ * "manage applications" settings page.
+ */
+ public static class OutOfSpaceDialog extends DialogFragment {
+ private InstallFailed mActivity;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ mActivity = (InstallFailed) context;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(mActivity)
+ .setTitle(R.string.out_of_space_dlg_title)
+ .setMessage(getString(R.string.out_of_space_dlg_text, mActivity.mLabel))
+ .setPositiveButton(R.string.manage_applications, (dialog, which) -> {
+ // launch manage applications
+ Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE");
+ startActivity(intent);
+ mActivity.finish();
+ })
+ .setNegativeButton(R.string.cancel, (dialog, which) -> mActivity.finish())
+ .create();
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
+
+ mActivity.finish();
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
new file mode 100755
index 0000000..22b1336
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallInstalling.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import static android.content.pm.PackageInstaller.SessionParams.UID_UNKNOWN;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.util.Log;
+import android.widget.Button;
+import android.widget.ProgressBar;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.content.PackageHelper;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Send package to the package manager and handle results from package manager. Once the
+ * installation succeeds, start {@link InstallSuccess} or {@link InstallFailed}.
+ * <p>This has two phases: First send the data to the package manager, then wait until the package
+ * manager processed the result.</p>
+ */
+public class InstallInstalling extends Activity {
+ private static final String LOG_TAG = InstallInstalling.class.getSimpleName();
+
+ private static final String SESSION_ID = "com.android.packageinstaller.SESSION_ID";
+ private static final String INSTALL_ID = "com.android.packageinstaller.INSTALL_ID";
+
+ private static final String BROADCAST_ACTION =
+ "com.android.packageinstaller.ACTION_INSTALL_COMMIT";
+
+ /** Listens to changed to the session and updates progress bar */
+ private PackageInstaller.SessionCallback mSessionCallback;
+
+ /** Task that sends the package to the package installer */
+ private InstallingAsyncTask mInstallingTask;
+
+ /** Id of the session to install the package */
+ private int mSessionId;
+
+ /** Id of the install event we wait for */
+ private int mInstallId;
+
+ /** URI of package to install */
+ private Uri mPackageURI;
+
+ /** The button that can cancel this dialog */
+ private Button mCancelButton;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.install_installing);
+
+ ApplicationInfo appInfo = getIntent()
+ .getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
+ mPackageURI = getIntent().getData();
+
+ if ("package".equals(mPackageURI.getScheme())) {
+ try {
+ getPackageManager().installExistingPackage(appInfo.packageName);
+ launchSuccess();
+ } catch (PackageManager.NameNotFoundException e) {
+ launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
+ }
+ } else {
+ final File sourceFile = new File(mPackageURI.getPath());
+ PackageUtil.initSnippetForNewApp(this, PackageUtil.getAppSnippet(this, appInfo,
+ sourceFile), R.id.app_snippet);
+
+ if (savedInstanceState != null) {
+ mSessionId = savedInstanceState.getInt(SESSION_ID);
+ mInstallId = savedInstanceState.getInt(INSTALL_ID);
+
+ // Reregister for result; might instantly call back if result was delivered while
+ // activity was destroyed
+ try {
+ InstallEventReceiver.addObserver(this, mInstallId,
+ this::launchFinishBasedOnResult);
+ } catch (EventResultPersister.OutOfIdsException e) {
+ // Does not happen
+ }
+ } else {
+ PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
+ PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+ params.installFlags = PackageManager.INSTALL_FULL_APP;
+ params.referrerUri = getIntent().getParcelableExtra(Intent.EXTRA_REFERRER);
+ params.originatingUri = getIntent()
+ .getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
+ params.originatingUid = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
+ UID_UNKNOWN);
+ params.installerPackageName =
+ getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
+
+ File file = new File(mPackageURI.getPath());
+ try {
+ PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0);
+ params.setAppPackageName(pkg.packageName);
+ params.setInstallLocation(pkg.installLocation);
+ params.setSize(
+ PackageHelper.calculateInstalledSize(pkg, false, params.abiOverride));
+ } catch (PackageParser.PackageParserException e) {
+ Log.e(LOG_TAG, "Cannot parse package " + file + ". Assuming defaults.");
+ Log.e(LOG_TAG,
+ "Cannot calculate installed size " + file + ". Try only apk size.");
+ params.setSize(file.length());
+ } catch (IOException e) {
+ Log.e(LOG_TAG,
+ "Cannot calculate installed size " + file + ". Try only apk size.");
+ params.setSize(file.length());
+ }
+
+ try {
+ mInstallId = InstallEventReceiver
+ .addObserver(this, EventResultPersister.GENERATE_NEW_ID,
+ this::launchFinishBasedOnResult);
+ } catch (EventResultPersister.OutOfIdsException e) {
+ launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
+ }
+
+ try {
+ mSessionId = getPackageManager().getPackageInstaller().createSession(params);
+ } catch (IOException e) {
+ launchFailure(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, null);
+ }
+ }
+
+ mCancelButton = (Button) findViewById(R.id.cancel_button);
+
+ mCancelButton.setOnClickListener(view -> {
+ if (mInstallingTask != null) {
+ mInstallingTask.cancel(true);
+ }
+
+ if (mSessionId > 0) {
+ getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+ mSessionId = 0;
+ }
+
+ setResult(RESULT_CANCELED);
+ finish();
+ });
+
+ mSessionCallback = new InstallSessionCallback();
+ }
+ }
+
+ /**
+ * Launch the "success" version of the final package installer dialog
+ */
+ private void launchSuccess() {
+ Intent successIntent = new Intent(getIntent());
+ successIntent.setClass(this, InstallSuccess.class);
+ successIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+
+ startActivity(successIntent);
+ finish();
+ }
+
+ /**
+ * Launch the "failure" version of the final package installer dialog
+ *
+ * @param legacyStatus The status as used internally in the package manager.
+ * @param statusMessage The status description.
+ */
+ private void launchFailure(int legacyStatus, String statusMessage) {
+ Intent failureIntent = new Intent(getIntent());
+ failureIntent.setClass(this, InstallFailed.class);
+ failureIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ failureIntent.putExtra(PackageInstaller.EXTRA_LEGACY_STATUS, legacyStatus);
+ failureIntent.putExtra(PackageInstaller.EXTRA_STATUS_MESSAGE, statusMessage);
+
+ startActivity(failureIntent);
+ finish();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+
+ getPackageManager().getPackageInstaller().registerSessionCallback(mSessionCallback);
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // This is the first onResume in a single life of the activity
+ if (mInstallingTask == null) {
+ PackageInstaller installer = getPackageManager().getPackageInstaller();
+ PackageInstaller.SessionInfo sessionInfo = installer.getSessionInfo(mSessionId);
+
+ if (sessionInfo != null && !sessionInfo.isActive()) {
+ mInstallingTask = new InstallingAsyncTask();
+ mInstallingTask.execute();
+ } else {
+ // we will receive a broadcast when the install is finished
+ mCancelButton.setEnabled(false);
+ setFinishOnTouchOutside(false);
+ }
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putInt(SESSION_ID, mSessionId);
+ outState.putInt(INSTALL_ID, mInstallId);
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (mCancelButton.isEnabled()) {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+
+ getPackageManager().getPackageInstaller().unregisterSessionCallback(mSessionCallback);
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mInstallingTask != null) {
+ mInstallingTask.cancel(true);
+ synchronized (mInstallingTask) {
+ while (!mInstallingTask.isDone) {
+ try {
+ mInstallingTask.wait();
+ } catch (InterruptedException e) {
+ Log.i(LOG_TAG, "Interrupted while waiting for installing task to cancel",
+ e);
+ }
+ }
+ }
+ }
+
+ InstallEventReceiver.removeObserver(this, mInstallId);
+
+ super.onDestroy();
+ }
+
+ /**
+ * Launch the appropriate finish activity (success or failed) for the installation result.
+ *
+ * @param statusCode The installation result.
+ * @param legacyStatus The installation as used internally in the package manager.
+ * @param statusMessage The detailed installation result.
+ */
+ private void launchFinishBasedOnResult(int statusCode, int legacyStatus, String statusMessage) {
+ if (statusCode == PackageInstaller.STATUS_SUCCESS) {
+ launchSuccess();
+ } else {
+ launchFailure(legacyStatus, statusMessage);
+ }
+ }
+
+
+ private class InstallSessionCallback extends PackageInstaller.SessionCallback {
+ @Override
+ public void onCreated(int sessionId) {
+ // empty
+ }
+
+ @Override
+ public void onBadgingChanged(int sessionId) {
+ // empty
+ }
+
+ @Override
+ public void onActiveChanged(int sessionId, boolean active) {
+ // empty
+ }
+
+ @Override
+ public void onProgressChanged(int sessionId, float progress) {
+ if (sessionId == mSessionId) {
+ ProgressBar progressBar = (ProgressBar)findViewById(R.id.progress_bar);
+ progressBar.setMax(Integer.MAX_VALUE);
+ progressBar.setProgress((int) (Integer.MAX_VALUE * progress));
+ }
+ }
+
+ @Override
+ public void onFinished(int sessionId, boolean success) {
+ // empty, finish is handled by InstallResultReceiver
+ }
+ }
+
+ /**
+ * Send the package to the package installer and then register a event result observer that
+ * will call {@link #launchFinishBasedOnResult(int, int, String)}
+ */
+ private final class InstallingAsyncTask extends AsyncTask<Void, Void,
+ PackageInstaller.Session> {
+ volatile boolean isDone;
+
+ @Override
+ protected PackageInstaller.Session doInBackground(Void... params) {
+ PackageInstaller.Session session;
+ try {
+ session = getPackageManager().getPackageInstaller().openSession(mSessionId);
+ } catch (IOException e) {
+ return null;
+ }
+
+ session.setStagingProgress(0);
+
+ try {
+ File file = new File(mPackageURI.getPath());
+
+ try (InputStream in = new FileInputStream(file)) {
+ long sizeBytes = file.length();
+ try (OutputStream out = session
+ .openWrite("PackageInstaller", 0, sizeBytes)) {
+ byte[] buffer = new byte[1024 * 1024];
+ while (true) {
+ int numRead = in.read(buffer);
+
+ if (numRead == -1) {
+ session.fsync(out);
+ break;
+ }
+
+ if (isCancelled()) {
+ session.close();
+ break;
+ }
+
+ out.write(buffer, 0, numRead);
+ if (sizeBytes > 0) {
+ float fraction = ((float) numRead / (float) sizeBytes);
+ session.addProgress(fraction);
+ }
+ }
+ }
+ }
+
+ return session;
+ } catch (IOException | SecurityException e) {
+ Log.e(LOG_TAG, "Could not write package", e);
+
+ session.close();
+
+ return null;
+ } finally {
+ synchronized (this) {
+ isDone = true;
+ notifyAll();
+ }
+ }
+ }
+
+ @Override
+ protected void onPostExecute(PackageInstaller.Session session) {
+ if (session != null) {
+ Intent broadcastIntent = new Intent(BROADCAST_ACTION);
+ broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ broadcastIntent.setPackage(getPackageName());
+ broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mInstallId);
+
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(
+ InstallInstalling.this,
+ mInstallId,
+ broadcastIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+
+ session.commit(pendingIntent.getIntentSender());
+ mCancelButton.setEnabled(false);
+ setFinishOnTouchOutside(false);
+ } else {
+ getPackageManager().getPackageInstaller().abandonSession(mSessionId);
+
+ if (!isCancelled()) {
+ launchFailure(PackageManager.INSTALL_FAILED_INVALID_APK, null);
+ }
+ }
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
new file mode 100644
index 0000000..bf72b65
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStaging.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import androidx.annotation.Nullable;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * If a package gets installed from an content URI this step loads the package and turns it into
+ * and installation from a file. Then it re-starts the installation as usual.
+ */
+public class InstallStaging extends Activity {
+ private static final String LOG_TAG = InstallStaging.class.getSimpleName();
+
+ private static final String STAGED_FILE = "STAGED_FILE";
+
+ /** Currently running task that loads the file from the content URI into a file */
+ private @Nullable StagingAsyncTask mStagingTask;
+
+ /** The file the package is in */
+ private @Nullable File mStagedFile;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.install_staging);
+
+ if (savedInstanceState != null) {
+ mStagedFile = new File(savedInstanceState.getString(STAGED_FILE));
+
+ if (!mStagedFile.exists()) {
+ mStagedFile = null;
+ }
+ }
+
+ findViewById(R.id.cancel_button).setOnClickListener(view -> {
+ if (mStagingTask != null) {
+ mStagingTask.cancel(true);
+ }
+ setResult(RESULT_CANCELED);
+ finish();
+ });
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ // This is the first onResume in a single life of the activity
+ if (mStagingTask == null) {
+ // File does not exist, or became invalid
+ if (mStagedFile == null) {
+ // Create file delayed to be able to show error
+ try {
+ mStagedFile = TemporaryFileManager.getStagedFile(this);
+ } catch (IOException e) {
+ showError();
+ return;
+ }
+ }
+
+ mStagingTask = new StagingAsyncTask();
+ mStagingTask.execute(getIntent().getData());
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putString(STAGED_FILE, mStagedFile.getPath());
+ }
+
+ @Override
+ protected void onDestroy() {
+ if (mStagingTask != null) {
+ mStagingTask.cancel(true);
+ }
+
+ super.onDestroy();
+ }
+
+ /**
+ * Show an error message and set result as error.
+ */
+ private void showError() {
+ (new ErrorDialog()).showAllowingStateLoss(getFragmentManager(), "error");
+
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT,
+ PackageManager.INSTALL_FAILED_INVALID_APK);
+ setResult(RESULT_FIRST_USER, result);
+ }
+
+ /**
+ * Dialog for errors while staging.
+ */
+ public static class ErrorDialog extends DialogFragment {
+ private Activity mActivity;
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
+ mActivity = (Activity) context;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog alertDialog = new AlertDialog.Builder(mActivity)
+ .setMessage(R.string.Parse_error_dlg_text)
+ .setPositiveButton(R.string.ok,
+ (dialog, which) -> mActivity.finish())
+ .create();
+ alertDialog.setCanceledOnTouchOutside(false);
+
+ return alertDialog;
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ super.onCancel(dialog);
+
+ mActivity.finish();
+ }
+ }
+
+ private final class StagingAsyncTask extends AsyncTask<Uri, Void, Boolean> {
+ @Override
+ protected Boolean doInBackground(Uri... params) {
+ if (params == null || params.length <= 0) {
+ return false;
+ }
+ Uri packageUri = params[0];
+ try (InputStream in = getContentResolver().openInputStream(packageUri)) {
+ // Despite the comments in ContentResolver#openInputStream the returned stream can
+ // be null.
+ if (in == null) {
+ return false;
+ }
+
+ try (OutputStream out = new FileOutputStream(mStagedFile)) {
+ byte[] buffer = new byte[1024 * 1024];
+ int bytesRead;
+ while ((bytesRead = in.read(buffer)) >= 0) {
+ // Be nice and respond to a cancellation
+ if (isCancelled()) {
+ return false;
+ }
+ out.write(buffer, 0, bytesRead);
+ }
+ }
+ } catch (IOException | SecurityException | IllegalStateException e) {
+ Log.w(LOG_TAG, "Error staging apk from content URI", e);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean success) {
+ if (success) {
+ // Now start the installation again from a file
+ Intent installIntent = new Intent(getIntent());
+ installIntent.setClass(InstallStaging.this, DeleteStagedFileOnResult.class);
+ installIntent.setData(Uri.fromFile(mStagedFile));
+
+ if (installIntent.getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ installIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ }
+
+ installIntent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
+ startActivity(installIntent);
+
+ InstallStaging.this.finish();
+ } else {
+ showError();
+ }
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
new file mode 100644
index 0000000..96c6c2f
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AppGlobals;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+
+/**
+ * Select which activity is the first visible activity of the installation and forward the intent to
+ * it.
+ */
+public class InstallStart extends Activity {
+ private static final String LOG_TAG = InstallStart.class.getSimpleName();
+
+ private static final String DOWNLOADS_AUTHORITY = "downloads";
+ private IPackageManager mIPackageManager;
+ private boolean mAbortInstall = false;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mIPackageManager = AppGlobals.getPackageManager();
+ Intent intent = getIntent();
+ String callingPackage = getCallingPackage();
+
+ // If the activity was started via a PackageInstaller session, we retrieve the calling
+ // package from that session
+ int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1);
+ if (callingPackage == null && sessionId != -1) {
+ PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
+ PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
+ callingPackage = (sessionInfo != null) ? sessionInfo.getInstallerPackageName() : null;
+ }
+
+ final ApplicationInfo sourceInfo = getSourceInfo(callingPackage);
+ final int originatingUid = getOriginatingUid(sourceInfo);
+ boolean isTrustedSource = false;
+ if (sourceInfo != null
+ && (sourceInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
+ isTrustedSource = intent.getBooleanExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, false);
+ }
+
+ if (!isTrustedSource && originatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) {
+ final int targetSdkVersion = getMaxTargetSdkVersionForUid(this, originatingUid);
+ if (targetSdkVersion < 0) {
+ Log.w(LOG_TAG, "Cannot get target sdk version for uid " + originatingUid);
+ // Invalid originating uid supplied. Abort install.
+ mAbortInstall = true;
+ } else if (targetSdkVersion >= Build.VERSION_CODES.O && !declaresAppOpPermission(
+ originatingUid, Manifest.permission.REQUEST_INSTALL_PACKAGES)) {
+ Log.e(LOG_TAG, "Requesting uid " + originatingUid + " needs to declare permission "
+ + Manifest.permission.REQUEST_INSTALL_PACKAGES);
+ mAbortInstall = true;
+ }
+ }
+ if (mAbortInstall) {
+ setResult(RESULT_CANCELED);
+ finish();
+ return;
+ }
+
+ Intent nextActivity = new Intent(intent);
+ nextActivity.setFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+
+ // The the installation source as the nextActivity thinks this activity is the source, hence
+ // set the originating UID and sourceInfo explicitly
+ nextActivity.putExtra(PackageInstallerActivity.EXTRA_CALLING_PACKAGE, callingPackage);
+ nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo);
+ nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid);
+
+ if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(intent.getAction())) {
+ nextActivity.setClass(this, PackageInstallerActivity.class);
+ } else {
+ Uri packageUri = intent.getData();
+
+ if (packageUri != null && (packageUri.getScheme().equals(ContentResolver.SCHEME_FILE)
+ || packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {
+ // Copy file to prevent it from being changed underneath this process
+ nextActivity.setClass(this, InstallStaging.class);
+ } else if (packageUri != null && packageUri.getScheme().equals(
+ PackageInstallerActivity.SCHEME_PACKAGE)) {
+ nextActivity.setClass(this, PackageInstallerActivity.class);
+ } else {
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT,
+ PackageManager.INSTALL_FAILED_INVALID_URI);
+ setResult(RESULT_FIRST_USER, result);
+
+ nextActivity = null;
+ }
+ }
+
+ if (nextActivity != null) {
+ startActivity(nextActivity);
+ }
+ finish();
+ }
+
+ private boolean declaresAppOpPermission(int uid, String permission) {
+ try {
+ final String[] packages = mIPackageManager.getAppOpPermissionPackages(permission);
+ if (packages == null) {
+ return false;
+ }
+ for (String packageName : packages) {
+ try {
+ if (uid == getPackageManager().getPackageUid(packageName, 0)) {
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Ignore and try the next package
+ }
+ }
+ } catch (RemoteException rexc) {
+ // If remote package manager cannot be reached, install will likely fail anyway.
+ }
+ return false;
+ }
+
+ /**
+ * @return the ApplicationInfo for the installation source (the calling package), if available
+ */
+ private ApplicationInfo getSourceInfo(@Nullable String callingPackage) {
+ if (callingPackage != null) {
+ try {
+ return getPackageManager().getApplicationInfo(callingPackage, 0);
+ } catch (PackageManager.NameNotFoundException ex) {
+ // ignore
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the originating uid if possible, or
+ * {@link android.content.pm.PackageInstaller.SessionParams#UID_UNKNOWN} if not available
+ *
+ * @param sourceInfo The source of this installation
+ * @return The UID of the installation source or UID_UNKNOWN
+ */
+ private int getOriginatingUid(@Nullable ApplicationInfo sourceInfo) {
+ // The originating uid from the intent. We only trust/use this if it comes from either
+ // the document manager app or the downloads provider
+ final int uidFromIntent = getIntent().getIntExtra(Intent.EXTRA_ORIGINATING_UID,
+ PackageInstaller.SessionParams.UID_UNKNOWN);
+
+ final int callingUid;
+ if (sourceInfo != null) {
+ callingUid = sourceInfo.uid;
+ } else {
+ try {
+ callingUid = ActivityManager.getService()
+ .getLaunchedFromUid(getActivityToken());
+ } catch (RemoteException ex) {
+ // Cannot reach ActivityManager. Aborting install.
+ Log.e(LOG_TAG, "Could not determine the launching uid.");
+ mAbortInstall = true;
+ return PackageInstaller.SessionParams.UID_UNKNOWN;
+ }
+ }
+ try {
+ if (mIPackageManager.checkUidPermission(Manifest.permission.MANAGE_DOCUMENTS,
+ callingUid) == PackageManager.PERMISSION_GRANTED) {
+ return uidFromIntent;
+ }
+ } catch (RemoteException rexc) {
+ // Ignore. Should not happen.
+ }
+ if (isSystemDownloadsProvider(callingUid)) {
+ return uidFromIntent;
+ }
+ // We don't trust uid from the intent. Use the calling uid instead.
+ return callingUid;
+ }
+
+ private boolean isSystemDownloadsProvider(int uid) {
+ final ProviderInfo downloadProviderPackage = getPackageManager().resolveContentProvider(
+ DOWNLOADS_AUTHORITY, 0);
+ if (downloadProviderPackage == null) {
+ // There seems to be no currently enabled downloads provider on the system.
+ return false;
+ }
+ final ApplicationInfo appInfo = downloadProviderPackage.applicationInfo;
+ return (appInfo.isSystemApp() && uid == appInfo.uid);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
new file mode 100644
index 0000000..ae902d3
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallSuccess.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.app.Activity;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import androidx.annotation.Nullable;
+import android.util.Log;
+import android.widget.Button;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * Finish installation: Return status code to the caller or display "success" UI to user
+ */
+public class InstallSuccess extends Activity {
+ private static final String LOG_TAG = InstallSuccess.class.getSimpleName();
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ // Return result if requested
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, PackageManager.INSTALL_SUCCEEDED);
+ setResult(Activity.RESULT_OK, result);
+ finish();
+ } else {
+ Intent intent = getIntent();
+ ApplicationInfo appInfo =
+ intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
+ Uri packageURI = intent.getData();
+
+ setContentView(R.layout.install_success);
+
+ // Set header icon and title
+ PackageUtil.AppSnippet as;
+ PackageManager pm = getPackageManager();
+
+ if ("package".equals(packageURI.getScheme())) {
+ as = new PackageUtil.AppSnippet(pm.getApplicationLabel(appInfo),
+ pm.getApplicationIcon(appInfo));
+ } else {
+ File sourceFile = new File(packageURI.getPath());
+ as = PackageUtil.getAppSnippet(this, appInfo, sourceFile);
+ }
+
+ PackageUtil.initSnippetForNewApp(this, as, R.id.app_snippet);
+
+ // Set up "done" button
+ findViewById(R.id.done_button).setOnClickListener(view -> {
+ if (appInfo.packageName != null) {
+ Log.i(LOG_TAG, "Finished installing " + appInfo.packageName);
+ }
+ finish();
+ });
+
+ // Enable or disable "launch" button
+ Intent launchIntent = getPackageManager().getLaunchIntentForPackage(
+ appInfo.packageName);
+ boolean enabled = false;
+ if (launchIntent != null) {
+ List<ResolveInfo> list = getPackageManager().queryIntentActivities(launchIntent,
+ 0);
+ if (list != null && list.size() > 0) {
+ enabled = true;
+ }
+ }
+
+ Button launchButton = (Button)findViewById(R.id.launch_button);
+ if (enabled) {
+ launchButton.setOnClickListener(view -> {
+ try {
+ startActivity(launchIntent);
+ } catch (ActivityNotFoundException | SecurityException e) {
+ Log.e(LOG_TAG, "Could not start activity", e);
+ }
+ finish();
+ });
+ } else {
+ launchButton.setEnabled(false);
+ }
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
new file mode 100644
index 0000000..83c91ea
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -0,0 +1,770 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package com.android.packageinstaller;
+
+import android.Manifest;
+import android.app.AlertDialog;
+import android.app.AppGlobals;
+import android.app.AppOpsManager;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageUserState;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+
+import com.android.packageinstaller.permission.ui.OverlayTouchActivity;
+
+import java.io.File;
+
+/**
+ * This activity is launched when a new application is installed via side loading
+ * The package is first parsed and the user is notified of parse errors via a dialog.
+ * If the package is successfully parsed, the user is notified to turn on the install unknown
+ * applications setting. A memory check is made at this point and the user is notified of out
+ * of memory conditions if any. If the package is already existing on the device,
+ * a confirmation dialog (to replace the existing package) is presented to the user.
+ * Based on the user response the package is then installed by launching InstallAppConfirm
+ * sub activity. All state transitions are handled in this activity
+ */
+public class PackageInstallerActivity extends OverlayTouchActivity implements OnClickListener {
+ private static final String TAG = "PackageInstaller";
+
+ private static final int REQUEST_TRUST_EXTERNAL_SOURCE = 1;
+
+ static final String SCHEME_PACKAGE = "package";
+
+ static final String EXTRA_CALLING_PACKAGE = "EXTRA_CALLING_PACKAGE";
+ static final String EXTRA_ORIGINAL_SOURCE_INFO = "EXTRA_ORIGINAL_SOURCE_INFO";
+ private static final String ALLOW_UNKNOWN_SOURCES_KEY =
+ PackageInstallerActivity.class.getName() + "ALLOW_UNKNOWN_SOURCES_KEY";
+
+ private int mSessionId = -1;
+ private Uri mPackageURI;
+ private Uri mOriginatingURI;
+ private Uri mReferrerURI;
+ private int mOriginatingUid = PackageInstaller.SessionParams.UID_UNKNOWN;
+ private String mOriginatingPackage; // The package name corresponding to #mOriginatingUid
+
+ private boolean localLOGV = false;
+ PackageManager mPm;
+ IPackageManager mIpm;
+ AppOpsManager mAppOpsManager;
+ UserManager mUserManager;
+ PackageInstaller mInstaller;
+ PackageInfo mPkgInfo;
+ String mCallingPackage;
+ ApplicationInfo mSourceInfo;
+
+ // ApplicationInfo object primarily used for already existing applications
+ private ApplicationInfo mAppInfo = null;
+
+ // Buttons to indicate user acceptance
+ private Button mOk;
+ private Button mCancel;
+
+ private PackageUtil.AppSnippet mAppSnippet;
+
+ static final String PREFS_ALLOWED_SOURCES = "allowed_sources";
+
+ // Dialog identifiers used in showDialog
+ private static final int DLG_BASE = 0;
+ private static final int DLG_PACKAGE_ERROR = DLG_BASE + 2;
+ private static final int DLG_OUT_OF_SPACE = DLG_BASE + 3;
+ private static final int DLG_INSTALL_ERROR = DLG_BASE + 4;
+ private static final int DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER = DLG_BASE + 5;
+ private static final int DLG_ANONYMOUS_SOURCE = DLG_BASE + 6;
+ private static final int DLG_NOT_SUPPORTED_ON_WEAR = DLG_BASE + 7;
+ private static final int DLG_EXTERNAL_SOURCE_BLOCKED = DLG_BASE + 8;
+ private static final int DLG_INSTALL_APPS_RESTRICTED_FOR_USER = DLG_BASE + 9;
+
+ // If unknown sources are temporary allowed
+ private boolean mAllowUnknownSources;
+
+ // Would the mOk button be enabled if this activity would be resumed
+ private boolean mEnableOk = false;
+
+ private void startInstallConfirm() {
+ int msg;
+
+ if (mAppInfo != null) {
+ msg = (mAppInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
+ ? R.string.install_confirm_question_update_system
+ : R.string.install_confirm_question_update;
+ } else {
+ // This is a new application with no permissions.
+ msg = R.string.install_confirm_question;
+ }
+
+ ((TextView) findViewById(R.id.install_confirm_question)).setText(msg);
+
+ mEnableOk = true;
+ mOk.setEnabled(true);
+ }
+
+ /**
+ * Replace any dialog shown by the dialog with the one for the given {@link #createDialog id}.
+ *
+ * @param id The dialog type to add
+ */
+ private void showDialogInner(int id) {
+ DialogFragment currentDialog =
+ (DialogFragment) getFragmentManager().findFragmentByTag("dialog");
+ if (currentDialog != null) {
+ currentDialog.dismissAllowingStateLoss();
+ }
+
+ DialogFragment newDialog = createDialog(id);
+ if (newDialog != null) {
+ newDialog.showAllowingStateLoss(getFragmentManager(), "dialog");
+ }
+ }
+
+ /**
+ * Create a new dialog.
+ *
+ * @param id The id of the dialog (determines dialog type)
+ *
+ * @return The dialog
+ */
+ private DialogFragment createDialog(int id) {
+ switch (id) {
+ case DLG_PACKAGE_ERROR:
+ return SimpleErrorDialog.newInstance(R.string.Parse_error_dlg_text);
+ case DLG_OUT_OF_SPACE:
+ return OutOfSpaceDialog.newInstance(
+ mPm.getApplicationLabel(mPkgInfo.applicationInfo));
+ case DLG_INSTALL_ERROR:
+ return InstallErrorDialog.newInstance(
+ mPm.getApplicationLabel(mPkgInfo.applicationInfo));
+ case DLG_NOT_SUPPORTED_ON_WEAR:
+ return NotSupportedOnWearDialog.newInstance();
+ case DLG_INSTALL_APPS_RESTRICTED_FOR_USER:
+ return SimpleErrorDialog.newInstance(
+ R.string.install_apps_user_restriction_dlg_text);
+ case DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER:
+ return SimpleErrorDialog.newInstance(
+ R.string.unknown_apps_user_restriction_dlg_text);
+ case DLG_EXTERNAL_SOURCE_BLOCKED:
+ return ExternalSourcesBlockedDialog.newInstance(mOriginatingPackage);
+ case DLG_ANONYMOUS_SOURCE:
+ return AnonymousSourceDialog.newInstance();
+ }
+ return null;
+ }
+
+ @Override
+ public void onActivityResult(int request, int result, Intent data) {
+ if (request == REQUEST_TRUST_EXTERNAL_SOURCE && result == RESULT_OK) {
+ // The user has just allowed this package to install other packages (via Settings).
+ mAllowUnknownSources = true;
+
+ // Log the fact that the app is requesting an install, and is now allowed to do it
+ // (before this point we could only log that it's requesting an install, but isn't
+ // allowed to do it yet).
+ int appOpCode =
+ AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES);
+ mAppOpsManager.noteOpNoThrow(appOpCode, mOriginatingUid, mOriginatingPackage);
+
+ DialogFragment currentDialog =
+ (DialogFragment) getFragmentManager().findFragmentByTag("dialog");
+ if (currentDialog != null) {
+ currentDialog.dismissAllowingStateLoss();
+ }
+
+ initiateInstall();
+ } else {
+ finish();
+ }
+ }
+
+ private String getPackageNameForUid(int sourceUid) {
+ String[] packagesForUid = mPm.getPackagesForUid(sourceUid);
+ if (packagesForUid == null) {
+ return null;
+ }
+ if (packagesForUid.length > 1) {
+ if (mCallingPackage != null) {
+ for (String packageName : packagesForUid) {
+ if (packageName.equals(mCallingPackage)) {
+ return packageName;
+ }
+ }
+ }
+ Log.i(TAG, "Multiple packages found for source uid " + sourceUid);
+ }
+ return packagesForUid[0];
+ }
+
+ private boolean isInstallRequestFromUnknownSource(Intent intent) {
+ if (mCallingPackage != null && intent.getBooleanExtra(
+ Intent.EXTRA_NOT_UNKNOWN_SOURCE, false)) {
+ if (mSourceInfo != null) {
+ if ((mSourceInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)
+ != 0) {
+ // Privileged apps can bypass unknown sources check if they want.
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private void initiateInstall() {
+ String pkgName = mPkgInfo.packageName;
+ // Check if there is already a package on the device with this name
+ // but it has been renamed to something else.
+ String[] oldName = mPm.canonicalToCurrentPackageNames(new String[] { pkgName });
+ if (oldName != null && oldName.length > 0 && oldName[0] != null) {
+ pkgName = oldName[0];
+ mPkgInfo.packageName = pkgName;
+ mPkgInfo.applicationInfo.packageName = pkgName;
+ }
+ // Check if package is already installed. display confirmation dialog if replacing pkg
+ try {
+ // This is a little convoluted because we want to get all uninstalled
+ // apps, but this may include apps with just data, and if it is just
+ // data we still want to count it as "installed".
+ mAppInfo = mPm.getApplicationInfo(pkgName,
+ PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ if ((mAppInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ mAppInfo = null;
+ }
+ } catch (NameNotFoundException e) {
+ mAppInfo = null;
+ }
+
+ startInstallConfirm();
+ }
+
+ void setPmResult(int pmResult) {
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, pmResult);
+ setResult(pmResult == PackageManager.INSTALL_SUCCEEDED
+ ? RESULT_OK : RESULT_FIRST_USER, result);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(null);
+
+ if (icicle != null) {
+ mAllowUnknownSources = icicle.getBoolean(ALLOW_UNKNOWN_SOURCES_KEY);
+ }
+
+ mPm = getPackageManager();
+ mIpm = AppGlobals.getPackageManager();
+ mAppOpsManager = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
+ mInstaller = mPm.getPackageInstaller();
+ mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
+
+ final Intent intent = getIntent();
+
+ mCallingPackage = intent.getStringExtra(EXTRA_CALLING_PACKAGE);
+ mSourceInfo = intent.getParcelableExtra(EXTRA_ORIGINAL_SOURCE_INFO);
+ mOriginatingUid = intent.getIntExtra(Intent.EXTRA_ORIGINATING_UID,
+ PackageInstaller.SessionParams.UID_UNKNOWN);
+ mOriginatingPackage = (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN)
+ ? getPackageNameForUid(mOriginatingUid) : null;
+
+
+ final Uri packageUri;
+
+ if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(intent.getAction())) {
+ final int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1);
+ final PackageInstaller.SessionInfo info = mInstaller.getSessionInfo(sessionId);
+ if (info == null || !info.sealed || info.resolvedBaseCodePath == null) {
+ Log.w(TAG, "Session " + mSessionId + " in funky state; ignoring");
+ finish();
+ return;
+ }
+
+ mSessionId = sessionId;
+ packageUri = Uri.fromFile(new File(info.resolvedBaseCodePath));
+ mOriginatingURI = null;
+ mReferrerURI = null;
+ } else {
+ mSessionId = -1;
+ packageUri = intent.getData();
+ mOriginatingURI = intent.getParcelableExtra(Intent.EXTRA_ORIGINATING_URI);
+ mReferrerURI = intent.getParcelableExtra(Intent.EXTRA_REFERRER);
+ }
+
+ // if there's nothing to do, quietly slip into the ether
+ if (packageUri == null) {
+ Log.w(TAG, "Unspecified source");
+ setPmResult(PackageManager.INSTALL_FAILED_INVALID_URI);
+ finish();
+ return;
+ }
+
+ if (DeviceUtils.isWear(this)) {
+ showDialogInner(DLG_NOT_SUPPORTED_ON_WEAR);
+ return;
+ }
+
+ boolean wasSetUp = processPackageUri(packageUri);
+ if (!wasSetUp) {
+ return;
+ }
+
+ // load dummy layout with OK button disabled until we override this layout in
+ // startInstallConfirm
+ bindUi(R.layout.install_confirm);
+ checkIfAllowedAndInitiateInstall();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ if (mOk != null) {
+ mOk.setEnabled(mEnableOk);
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ if (mOk != null) {
+ // Don't allow the install button to be clicked as there might be overlays
+ mOk.setEnabled(false);
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putBoolean(ALLOW_UNKNOWN_SOURCES_KEY, mAllowUnknownSources);
+ }
+
+ private void bindUi(int layout) {
+ setContentView(layout);
+
+ mOk = (Button) findViewById(R.id.ok_button);
+ mCancel = (Button)findViewById(R.id.cancel_button);
+ mOk.setOnClickListener(this);
+ mCancel.setOnClickListener(this);
+
+ mOk.setEnabled(false);
+
+ PackageUtil.initSnippetForNewApp(this, mAppSnippet, R.id.app_snippet);
+ }
+
+ /**
+ * Check if it is allowed to install the package and initiate install if allowed. If not allowed
+ * show the appropriate dialog.
+ */
+ private void checkIfAllowedAndInitiateInstall() {
+ // Check for install apps user restriction first.
+ final int installAppsRestrictionSource = mUserManager.getUserRestrictionSource(
+ UserManager.DISALLOW_INSTALL_APPS, Process.myUserHandle());
+ if ((installAppsRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
+ showDialogInner(DLG_INSTALL_APPS_RESTRICTED_FOR_USER);
+ return;
+ } else if (installAppsRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
+ startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
+ finish();
+ return;
+ }
+
+ if (mAllowUnknownSources || !isInstallRequestFromUnknownSource(getIntent())) {
+ initiateInstall();
+ } else {
+ // Check for unknown sources restriction
+ final int unknownSourcesRestrictionSource = mUserManager.getUserRestrictionSource(
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle());
+ if ((unknownSourcesRestrictionSource & UserManager.RESTRICTION_SOURCE_SYSTEM) != 0) {
+ showDialogInner(DLG_UNKNOWN_SOURCES_RESTRICTED_FOR_USER);
+ } else if (unknownSourcesRestrictionSource != UserManager.RESTRICTION_NOT_SET) {
+ startActivity(new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS));
+ finish();
+ } else {
+ handleUnknownSources();
+ }
+ }
+ }
+
+ private void handleUnknownSources() {
+ if (mOriginatingPackage == null) {
+ Log.i(TAG, "No source found for package " + mPkgInfo.packageName);
+ showDialogInner(DLG_ANONYMOUS_SOURCE);
+ return;
+ }
+ // Shouldn't use static constant directly, see b/65534401.
+ final int appOpCode =
+ AppOpsManager.permissionToOpCode(Manifest.permission.REQUEST_INSTALL_PACKAGES);
+ final int appOpMode = mAppOpsManager.noteOpNoThrow(appOpCode,
+ mOriginatingUid, mOriginatingPackage);
+ switch (appOpMode) {
+ case AppOpsManager.MODE_DEFAULT:
+ try {
+ int result = mIpm.checkUidPermission(
+ Manifest.permission.REQUEST_INSTALL_PACKAGES, mOriginatingUid);
+ if (result == PackageManager.PERMISSION_GRANTED) {
+ initiateInstall();
+ break;
+ }
+ } catch (RemoteException exc) {
+ Log.e(TAG, "Unable to talk to package manager");
+ }
+ mAppOpsManager.setMode(appOpCode, mOriginatingUid,
+ mOriginatingPackage, AppOpsManager.MODE_ERRORED);
+ // fall through
+ case AppOpsManager.MODE_ERRORED:
+ showDialogInner(DLG_EXTERNAL_SOURCE_BLOCKED);
+ break;
+ case AppOpsManager.MODE_ALLOWED:
+ initiateInstall();
+ break;
+ default:
+ Log.e(TAG, "Invalid app op mode " + appOpMode
+ + " for OP_REQUEST_INSTALL_PACKAGES found for uid " + mOriginatingUid);
+ finish();
+ break;
+ }
+ }
+
+ /**
+ * Parse the Uri and set up the installer for this package.
+ *
+ * @param packageUri The URI to parse
+ *
+ * @return {@code true} iff the installer could be set up
+ */
+ private boolean processPackageUri(final Uri packageUri) {
+ mPackageURI = packageUri;
+
+ final String scheme = packageUri.getScheme();
+
+ switch (scheme) {
+ case SCHEME_PACKAGE: {
+ try {
+ mPkgInfo = mPm.getPackageInfo(packageUri.getSchemeSpecificPart(),
+ PackageManager.GET_PERMISSIONS
+ | PackageManager.MATCH_UNINSTALLED_PACKAGES);
+ } catch (NameNotFoundException e) {
+ }
+ if (mPkgInfo == null) {
+ Log.w(TAG, "Requested package " + packageUri.getScheme()
+ + " not available. Discontinuing installation");
+ showDialogInner(DLG_PACKAGE_ERROR);
+ setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
+ return false;
+ }
+ mAppSnippet = new PackageUtil.AppSnippet(mPm.getApplicationLabel(mPkgInfo.applicationInfo),
+ mPm.getApplicationIcon(mPkgInfo.applicationInfo));
+ } break;
+
+ case ContentResolver.SCHEME_FILE: {
+ File sourceFile = new File(packageUri.getPath());
+ PackageParser.Package parsed = PackageUtil.getPackageInfo(this, sourceFile);
+
+ // Check for parse errors
+ if (parsed == null) {
+ Log.w(TAG, "Parse error when parsing manifest. Discontinuing installation");
+ showDialogInner(DLG_PACKAGE_ERROR);
+ setPmResult(PackageManager.INSTALL_FAILED_INVALID_APK);
+ return false;
+ }
+ mPkgInfo = PackageParser.generatePackageInfo(parsed, null,
+ PackageManager.GET_PERMISSIONS, 0, 0, null,
+ new PackageUserState());
+ mAppSnippet = PackageUtil.getAppSnippet(this, mPkgInfo.applicationInfo, sourceFile);
+ } break;
+
+ default: {
+ throw new IllegalArgumentException("Unexpected URI scheme " + packageUri);
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (mSessionId != -1) {
+ mInstaller.setPermissionsResult(mSessionId, false);
+ }
+ super.onBackPressed();
+ }
+
+ public void onClick(View v) {
+ if (v == mOk) {
+ if (mOk.isEnabled()) {
+ if (mSessionId != -1) {
+ mInstaller.setPermissionsResult(mSessionId, true);
+ finish();
+ } else {
+ startInstall();
+ }
+ }
+ } else if (v == mCancel) {
+ // Cancel and finish
+ setResult(RESULT_CANCELED);
+ if (mSessionId != -1) {
+ mInstaller.setPermissionsResult(mSessionId, false);
+ }
+ finish();
+ }
+ }
+
+ private void startInstall() {
+ // Start subactivity to actually install the application
+ Intent newIntent = new Intent();
+ newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO,
+ mPkgInfo.applicationInfo);
+ newIntent.setData(mPackageURI);
+ newIntent.setClass(this, InstallInstalling.class);
+ String installerPackageName = getIntent().getStringExtra(
+ Intent.EXTRA_INSTALLER_PACKAGE_NAME);
+ if (mOriginatingURI != null) {
+ newIntent.putExtra(Intent.EXTRA_ORIGINATING_URI, mOriginatingURI);
+ }
+ if (mReferrerURI != null) {
+ newIntent.putExtra(Intent.EXTRA_REFERRER, mReferrerURI);
+ }
+ if (mOriginatingUid != PackageInstaller.SessionParams.UID_UNKNOWN) {
+ newIntent.putExtra(Intent.EXTRA_ORIGINATING_UID, mOriginatingUid);
+ }
+ if (installerPackageName != null) {
+ newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME,
+ installerPackageName);
+ }
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
+ }
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ if(localLOGV) Log.i(TAG, "downloaded app uri="+mPackageURI);
+ startActivity(newIntent);
+ finish();
+ }
+
+ /**
+ * A simple error dialog showing a message
+ */
+ public static class SimpleErrorDialog extends DialogFragment {
+ private static final String MESSAGE_KEY =
+ SimpleErrorDialog.class.getName() + "MESSAGE_KEY";
+
+ static SimpleErrorDialog newInstance(@StringRes int message) {
+ SimpleErrorDialog dialog = new SimpleErrorDialog();
+
+ Bundle args = new Bundle();
+ args.putInt(MESSAGE_KEY, message);
+ dialog.setArguments(args);
+
+ return dialog;
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(getArguments().getInt(MESSAGE_KEY))
+ .setPositiveButton(R.string.ok, (dialog, which) -> getActivity().finish())
+ .create();
+ }
+ }
+
+ /**
+ * Dialog to show when the source of apk can not be identified
+ */
+ public static class AnonymousSourceDialog extends DialogFragment {
+ static AnonymousSourceDialog newInstance() {
+ return new AnonymousSourceDialog();
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(R.string.anonymous_source_warning)
+ .setPositiveButton(R.string.anonymous_source_continue,
+ ((dialog, which) -> {
+ PackageInstallerActivity activity = ((PackageInstallerActivity)
+ getActivity());
+
+ activity.mAllowUnknownSources = true;
+ activity.initiateInstall();
+ }))
+ .setNegativeButton(R.string.cancel, ((dialog, which) -> getActivity().finish()))
+ .create();
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ getActivity().finish();
+ }
+ }
+
+ /**
+ * An error dialog shown when the app is not supported on wear
+ */
+ public static class NotSupportedOnWearDialog extends SimpleErrorDialog {
+ static SimpleErrorDialog newInstance() {
+ return SimpleErrorDialog.newInstance(R.string.wear_not_allowed_dlg_text);
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ getActivity().setResult(RESULT_OK);
+ getActivity().finish();
+ }
+ }
+
+ /**
+ * An error dialog shown when the device is out of space
+ */
+ public static class OutOfSpaceDialog extends AppErrorDialog {
+ static AppErrorDialog newInstance(@NonNull CharSequence applicationLabel) {
+ OutOfSpaceDialog dialog = new OutOfSpaceDialog();
+ dialog.setArgument(applicationLabel);
+ return dialog;
+ }
+
+ @Override
+ protected Dialog createDialog(@NonNull CharSequence argument) {
+ String dlgText = getString(R.string.out_of_space_dlg_text, argument);
+ return new AlertDialog.Builder(getActivity())
+ .setMessage(dlgText)
+ .setPositiveButton(R.string.manage_applications, (dialog, which) -> {
+ // launch manage applications
+ Intent intent = new Intent("android.intent.action.MANAGE_PACKAGE_STORAGE");
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ getActivity().finish();
+ })
+ .setNegativeButton(R.string.cancel, (dialog, which) -> getActivity().finish())
+ .create();
+ }
+ }
+
+ /**
+ * A generic install-error dialog
+ */
+ public static class InstallErrorDialog extends AppErrorDialog {
+ static AppErrorDialog newInstance(@NonNull CharSequence applicationLabel) {
+ InstallErrorDialog dialog = new InstallErrorDialog();
+ dialog.setArgument(applicationLabel);
+ return dialog;
+ }
+
+ @Override
+ protected Dialog createDialog(@NonNull CharSequence argument) {
+ return new AlertDialog.Builder(getActivity())
+ .setNeutralButton(R.string.ok, (dialog, which) -> getActivity().finish())
+ .setMessage(getString(R.string.install_failed_msg, argument))
+ .create();
+ }
+ }
+
+ /**
+ * An error dialog shown when external sources are not allowed
+ */
+ public static class ExternalSourcesBlockedDialog extends AppErrorDialog {
+ static AppErrorDialog newInstance(@NonNull String originationPkg) {
+ ExternalSourcesBlockedDialog dialog = new ExternalSourcesBlockedDialog();
+ dialog.setArgument(originationPkg);
+ return dialog;
+ }
+
+ @Override
+ protected Dialog createDialog(@NonNull CharSequence argument) {
+ try {
+ PackageManager pm = getActivity().getPackageManager();
+
+ ApplicationInfo sourceInfo = pm.getApplicationInfo(argument.toString(), 0);
+
+ return new AlertDialog.Builder(getActivity())
+ .setTitle(pm.getApplicationLabel(sourceInfo))
+ .setIcon(pm.getApplicationIcon(sourceInfo))
+ .setMessage(R.string.untrusted_external_source_warning)
+ .setPositiveButton(R.string.external_sources_settings,
+ (dialog, which) -> {
+ Intent settingsIntent = new Intent();
+ settingsIntent.setAction(
+ Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
+ final Uri packageUri = Uri.parse("package:" + argument);
+ settingsIntent.setData(packageUri);
+ try {
+ getActivity().startActivityForResult(settingsIntent,
+ REQUEST_TRUST_EXTERNAL_SOURCE);
+ } catch (ActivityNotFoundException exc) {
+ Log.e(TAG, "Settings activity not found for action: "
+ + Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
+ }
+ })
+ .setNegativeButton(R.string.cancel,
+ (dialog, which) -> getActivity().finish())
+ .create();
+ } catch (NameNotFoundException e) {
+ Log.e(TAG, "Did not find app info for " + argument);
+ getActivity().finish();
+ return null;
+ }
+ }
+ }
+
+ /**
+ * Superclass for all error dialogs. Stores a single CharSequence argument
+ */
+ public abstract static class AppErrorDialog extends DialogFragment {
+ private static final String ARGUMENT_KEY = AppErrorDialog.class.getName() + "ARGUMENT_KEY";
+
+ protected void setArgument(@NonNull CharSequence argument) {
+ Bundle args = new Bundle();
+ args.putCharSequence(ARGUMENT_KEY, argument);
+ setArguments(args);
+ }
+
+ protected abstract Dialog createDialog(@NonNull CharSequence argument);
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ return createDialog(getArguments().getString(ARGUMENT_KEY));
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ getActivity().finish();
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java
new file mode 100644
index 0000000..9b7e64e
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 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.packageinstaller;
+
+import android.app.Application;
+import android.content.pm.PackageItemInfo;
+
+public class PackageInstallerApplication extends Application {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ PackageItemInfo.setForceSafeLabels(true);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
new file mode 100644
index 0000000..68daed7
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageUtil.java
@@ -0,0 +1,210 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package com.android.packageinstaller;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.PackageParserException;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.UserHandle;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.io.File;
+
+/**
+ * This is a utility class for defining some utility methods and constants
+ * used in the package installer application.
+ */
+public class PackageUtil {
+ private static final String LOG_TAG = PackageUtil.class.getSimpleName();
+
+ public static final String PREFIX="com.android.packageinstaller.";
+ public static final String INTENT_ATTR_INSTALL_STATUS = PREFIX+"installStatus";
+ public static final String INTENT_ATTR_APPLICATION_INFO=PREFIX+"applicationInfo";
+ public static final String INTENT_ATTR_PERMISSIONS_LIST=PREFIX+"PermissionsList";
+ //intent attribute strings related to uninstall
+ public static final String INTENT_ATTR_PACKAGE_NAME=PREFIX+"PackageName";
+
+ /**
+ * Utility method to get package information for a given {@link File}
+ */
+ public static PackageParser.Package getPackageInfo(Context context, File sourceFile) {
+ final PackageParser parser = new PackageParser();
+ parser.setCallback(new PackageParser.CallbackImpl(context.getPackageManager()));
+ try {
+ return parser.parsePackage(sourceFile, 0);
+ } catch (PackageParserException e) {
+ return null;
+ }
+ }
+
+ public static View initSnippet(View snippetView, CharSequence label, Drawable icon) {
+ ((ImageView)snippetView.findViewById(R.id.app_icon)).setImageDrawable(icon);
+ ((TextView)snippetView.findViewById(R.id.app_name)).setText(label);
+ return snippetView;
+ }
+
+ /**
+ * Utility method to display a snippet of an installed application.
+ * The content view should have been set on context before invoking this method.
+ * appSnippet view should include R.id.app_icon and R.id.app_name
+ * defined on it.
+ *
+ * @param pContext context of package that can load the resources
+ * @param componentInfo ComponentInfo object whose resources are to be loaded
+ * @param snippetView the snippet view
+ */
+ public static View initSnippetForInstalledApp(Context pContext,
+ ApplicationInfo appInfo, View snippetView) {
+ return initSnippetForInstalledApp(pContext, appInfo, snippetView, null);
+ }
+
+ /**
+ * Utility method to display a snippet of an installed application.
+ * The content view should have been set on context before invoking this method.
+ * appSnippet view should include R.id.app_icon and R.id.app_name
+ * defined on it.
+ *
+ * @param pContext context of package that can load the resources
+ * @param componentInfo ComponentInfo object whose resources are to be loaded
+ * @param snippetView the snippet view
+ * @param UserHandle user that the app si installed for.
+ */
+ public static View initSnippetForInstalledApp(Context pContext,
+ ApplicationInfo appInfo, View snippetView, UserHandle user) {
+ final PackageManager pm = pContext.getPackageManager();
+ Drawable icon = appInfo.loadIcon(pm);
+ if (user != null) {
+ icon = pContext.getPackageManager().getUserBadgedIcon(icon, user);
+ }
+ return initSnippet(
+ snippetView,
+ appInfo.loadLabel(pm),
+ icon);
+ }
+
+ /**
+ * Utility method to display application snippet of a new package.
+ * The content view should have been set on context before invoking this method.
+ * appSnippet view should include R.id.app_icon and R.id.app_name
+ * defined on it.
+ *
+ * @param pContext context of package that can load the resources
+ * @param as The resources to be loaded
+ * @param snippetId view id of app snippet view
+ */
+ @NonNull public static View initSnippetForNewApp(@NonNull Activity pContext,
+ @NonNull AppSnippet as, int snippetId) {
+ View appSnippet = pContext.findViewById(snippetId);
+ if (as.icon != null) {
+ ((ImageView) appSnippet.findViewById(R.id.app_icon)).setImageDrawable(as.icon);
+ }
+ ((TextView)appSnippet.findViewById(R.id.app_name)).setText(as.label);
+ return appSnippet;
+ }
+
+ static public class AppSnippet {
+ @NonNull public CharSequence label;
+ @Nullable public Drawable icon;
+ public AppSnippet(@NonNull CharSequence label, @Nullable Drawable icon) {
+ this.label = label;
+ this.icon = icon;
+ }
+ }
+
+ /**
+ * Utility method to load application label
+ *
+ * @param pContext context of package that can load the resources
+ * @param appInfo ApplicationInfo object of package whose resources are to be loaded
+ * @param sourceFile File the package is in
+ */
+ public static AppSnippet getAppSnippet(
+ Activity pContext, ApplicationInfo appInfo, File sourceFile) {
+ final String archiveFilePath = sourceFile.getAbsolutePath();
+ Resources pRes = pContext.getResources();
+ AssetManager assmgr = new AssetManager();
+ assmgr.addAssetPath(archiveFilePath);
+ Resources res = new Resources(assmgr, pRes.getDisplayMetrics(), pRes.getConfiguration());
+ CharSequence label = null;
+ // Try to load the label from the package's resources. If an app has not explicitly
+ // specified any label, just use the package name.
+ if (appInfo.labelRes != 0) {
+ try {
+ label = res.getText(appInfo.labelRes);
+ } catch (Resources.NotFoundException e) {
+ }
+ }
+ if (label == null) {
+ label = (appInfo.nonLocalizedLabel != null) ?
+ appInfo.nonLocalizedLabel : appInfo.packageName;
+ }
+ Drawable icon = null;
+ // Try to load the icon from the package's resources. If an app has not explicitly
+ // specified any resource, just use the default icon for now.
+ try {
+ if (appInfo.icon != 0) {
+ try {
+ icon = res.getDrawable(appInfo.icon);
+ } catch (Resources.NotFoundException e) {
+ }
+ }
+ if (icon == null) {
+ icon = pContext.getPackageManager().getDefaultActivityIcon();
+ }
+ } catch (OutOfMemoryError e) {
+ Log.i(LOG_TAG, "Could not load app icon", e);
+ }
+ return new PackageUtil.AppSnippet(label, icon);
+ }
+
+ /**
+ * Get the maximum target sdk for a UID.
+ *
+ * @param context The context to use
+ * @param uid The UID requesting the install/uninstall
+ *
+ * @return The maximum target SDK or -1 if the uid does not match any packages.
+ */
+ static int getMaxTargetSdkVersionForUid(@NonNull Context context, int uid) {
+ PackageManager pm = context.getPackageManager();
+ final String[] packages = pm.getPackagesForUid(uid);
+ int targetSdkVersion = -1;
+ if (packages != null) {
+ for (String packageName : packages) {
+ try {
+ ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
+ targetSdkVersion = Math.max(targetSdkVersion, info.targetSdkVersion);
+ } catch (PackageManager.NameNotFoundException e) {
+ // Ignore and try the next package
+ }
+ }
+ }
+ return targetSdkVersion;
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/RemoveReceiver.java b/packages/PackageInstaller/src/com/android/packageinstaller/RemoveReceiver.java
new file mode 100644
index 0000000..7d8064d
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/RemoveReceiver.java
@@ -0,0 +1,42 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package com.android.packageinstaller;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+
+public class RemoveReceiver extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(intent.getAction())) {
+ Uri uri = intent.getData();
+ String pkg = uri != null ? uri.getSchemeSpecificPart() : null;
+ if (pkg != null) {
+ SharedPreferences prefs = context.getSharedPreferences(
+ PackageInstallerActivity.PREFS_ALLOWED_SOURCES,
+ Context.MODE_PRIVATE);
+ if (prefs.getBoolean(pkg, false)) {
+ prefs.edit().remove(pkg).apply();
+ }
+ }
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/TemporaryFileManager.java b/packages/PackageInstaller/src/com/android/packageinstaller/TemporaryFileManager.java
new file mode 100644
index 0000000..66e93b3
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/TemporaryFileManager.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.SystemClock;
+import androidx.annotation.NonNull;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Manages files of the package installer and resets state during boot.
+ */
+public class TemporaryFileManager extends BroadcastReceiver {
+ private static final String LOG_TAG = TemporaryFileManager.class.getSimpleName();
+
+ /**
+ * Create a new file to hold a staged file.
+ *
+ * @param context The context of the caller
+ *
+ * @return A new file
+ */
+ @NonNull
+ public static File getStagedFile(@NonNull Context context) throws IOException {
+ return File.createTempFile("package", ".apk", context.getNoBackupFilesDir());
+ }
+
+ /**
+ * Get the file used to store the results of installs.
+ *
+ * @param context The context of the caller
+ *
+ * @return the file used to store the results of installs
+ */
+ @NonNull
+ public static File getInstallStateFile(@NonNull Context context) {
+ return new File(context.getNoBackupFilesDir(), "install_results.xml");
+ }
+
+ /**
+ * Get the file used to store the results of uninstalls.
+ *
+ * @param context The context of the caller
+ *
+ * @return the file used to store the results of uninstalls
+ */
+ @NonNull
+ public static File getUninstallStateFile(@NonNull Context context) {
+ return new File(context.getNoBackupFilesDir(), "uninstall_results.xml");
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ long systemBootTime = System.currentTimeMillis() - SystemClock.elapsedRealtime();
+
+ File[] filesOnBoot = context.getNoBackupFilesDir().listFiles();
+
+ if (filesOnBoot == null) {
+ return;
+ }
+
+ for (int i = 0; i < filesOnBoot.length; i++) {
+ File fileOnBoot = filesOnBoot[i];
+
+ if (systemBootTime > fileOnBoot.lastModified()) {
+ boolean wasDeleted = fileOnBoot.delete();
+ if (!wasDeleted) {
+ Log.w(LOG_TAG, "Could not delete " + fileOnBoot.getName() + " onBoot");
+ }
+ } else {
+ Log.w(LOG_TAG, fileOnBoot.getName() + " was created before onBoot broadcast was "
+ + "received");
+ }
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallEventReceiver.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallEventReceiver.java
new file mode 100644
index 0000000..ad3cd4c
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallEventReceiver.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import androidx.annotation.NonNull;
+
+/**
+ * Receives uninstall events and persists them using a {@link EventResultPersister}.
+ */
+public class UninstallEventReceiver extends BroadcastReceiver {
+ private static final Object sLock = new Object();
+ private static EventResultPersister sReceiver;
+
+ /**
+ * Get the event receiver persisting the results
+ *
+ * @return The event receiver.
+ */
+ @NonNull private static EventResultPersister getReceiver(@NonNull Context context) {
+ synchronized (sLock) {
+ if (sReceiver == null) {
+ sReceiver = new EventResultPersister(
+ TemporaryFileManager.getUninstallStateFile(context));
+ }
+ }
+
+ return sReceiver;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ getReceiver(context).onEventReceived(context, intent);
+ }
+
+ /**
+ * Add an observer. If there is already an event for this id, call back inside of this call.
+ *
+ * @param context A context of the current app
+ * @param id The id the observer is for or {@code GENERATE_NEW_ID} to generate a new one.
+ * @param observer The observer to call back.
+ *
+ * @return The id for this event
+ */
+ static int addObserver(@NonNull Context context, int id,
+ @NonNull EventResultPersister.EventResultObserver observer)
+ throws EventResultPersister.OutOfIdsException {
+ return getReceiver(context).addObserver(id, observer);
+ }
+
+ /**
+ * Remove a observer.
+ *
+ * @param context A context of the current app
+ * @param id The id the observer was added for
+ */
+ static void removeObserver(@NonNull Context context, int id) {
+ getReceiver(context).removeObserver(id);
+ }
+
+ /**
+ * @param context A context of the current app
+ *
+ * @return A new uninstall id
+ */
+ static int getNewId(@NonNull Context context) throws EventResultPersister.OutOfIdsException {
+ return getReceiver(context).getNewId();
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallFinish.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallFinish.java
new file mode 100644
index 0000000..8282c83
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallFinish.java
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.admin.IDevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.graphics.drawable.Icon;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import androidx.annotation.NonNull;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.util.List;
+
+/**
+ * Finish an uninstallation and show Toast on success or failure notification.
+ */
+public class UninstallFinish extends BroadcastReceiver {
+ private static final String LOG_TAG = UninstallFinish.class.getSimpleName();
+
+ private static final String UNINSTALL_FAILURE_CHANNEL = "uninstall failure";
+
+ static final String EXTRA_UNINSTALL_ID = "com.android.packageinstaller.extra.UNINSTALL_ID";
+ static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL";
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ int returnCode = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, 0);
+
+ Log.i(LOG_TAG, "Uninstall finished extras=" + intent.getExtras());
+
+ if (returnCode == PackageInstaller.STATUS_PENDING_USER_ACTION) {
+ context.startActivity(intent.getParcelableExtra(Intent.EXTRA_INTENT));
+ return;
+ }
+
+ int uninstallId = intent.getIntExtra(EXTRA_UNINSTALL_ID, 0);
+ ApplicationInfo appInfo = intent.getParcelableExtra(
+ PackageUtil.INTENT_ATTR_APPLICATION_INFO);
+ String appLabel = intent.getStringExtra(EXTRA_APP_LABEL);
+ boolean allUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
+
+ NotificationManager notificationManager =
+ context.getSystemService(NotificationManager.class);
+ UserManager userManager = context.getSystemService(UserManager.class);
+
+ NotificationChannel uninstallFailureChannel = new NotificationChannel(
+ UNINSTALL_FAILURE_CHANNEL,
+ context.getString(R.string.uninstall_failure_notification_channel),
+ NotificationManager.IMPORTANCE_DEFAULT);
+ notificationManager.createNotificationChannel(uninstallFailureChannel);
+
+ Notification.Builder uninstallFailedNotification = new Notification.Builder(context,
+ UNINSTALL_FAILURE_CHANNEL);
+
+ switch (returnCode) {
+ case PackageInstaller.STATUS_SUCCESS:
+ notificationManager.cancel(uninstallId);
+
+ Toast.makeText(context, context.getString(R.string.uninstall_done_app, appLabel),
+ Toast.LENGTH_LONG).show();
+ return;
+ case PackageInstaller.STATUS_FAILURE_BLOCKED: {
+ int legacyStatus = intent.getIntExtra(PackageInstaller.EXTRA_LEGACY_STATUS, 0);
+
+ switch (legacyStatus) {
+ case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER: {
+ IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
+ // Find out if the package is an active admin for some non-current user.
+ int myUserId = UserHandle.myUserId();
+ UserInfo otherBlockingUser = null;
+ for (UserInfo user : userManager.getUsers()) {
+ // We only catch the case when the user in question is neither the
+ // current user nor its profile.
+ if (isProfileOfOrSame(userManager, myUserId, user.id)) {
+ continue;
+ }
+
+ try {
+ if (dpm.packageHasActiveAdmins(appInfo.packageName, user.id)) {
+ otherBlockingUser = user;
+ break;
+ }
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Failed to talk to package manager", e);
+ }
+ }
+ if (otherBlockingUser == null) {
+ Log.d(LOG_TAG, "Uninstall failed because " + appInfo.packageName
+ + " is a device admin");
+
+ addDeviceManagerButton(context, uninstallFailedNotification);
+ setBigText(uninstallFailedNotification, context.getString(
+ R.string.uninstall_failed_device_policy_manager));
+ } else {
+ Log.d(LOG_TAG, "Uninstall failed because " + appInfo.packageName
+ + " is a device admin of user " + otherBlockingUser);
+
+ setBigText(uninstallFailedNotification, String.format(context.getString(
+ R.string.uninstall_failed_device_policy_manager_of_user),
+ otherBlockingUser.name));
+ }
+ break;
+ }
+ case PackageManager.DELETE_FAILED_OWNER_BLOCKED: {
+ IPackageManager packageManager = IPackageManager.Stub.asInterface(
+ ServiceManager.getService("package"));
+
+ List<UserInfo> users = userManager.getUsers();
+ int blockingUserId = UserHandle.USER_NULL;
+ for (int i = 0; i < users.size(); ++i) {
+ final UserInfo user = users.get(i);
+ try {
+ if (packageManager.getBlockUninstallForUser(appInfo.packageName,
+ user.id)) {
+ blockingUserId = user.id;
+ break;
+ }
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ Log.e(LOG_TAG, "Failed to talk to package manager", e);
+ }
+ }
+
+ int myUserId = UserHandle.myUserId();
+ if (isProfileOfOrSame(userManager, myUserId, blockingUserId)) {
+ addDeviceManagerButton(context, uninstallFailedNotification);
+ } else {
+ addManageUsersButton(context, uninstallFailedNotification);
+ }
+
+ if (blockingUserId == UserHandle.USER_NULL) {
+ Log.d(LOG_TAG,
+ "Uninstall failed for " + appInfo.packageName + " with code "
+ + returnCode + " no blocking user");
+ } else if (blockingUserId == UserHandle.USER_SYSTEM) {
+ setBigText(uninstallFailedNotification,
+ context.getString(R.string.uninstall_blocked_device_owner));
+ } else {
+ if (allUsers) {
+ setBigText(uninstallFailedNotification,
+ context.getString(
+ R.string.uninstall_all_blocked_profile_owner));
+ } else {
+ setBigText(uninstallFailedNotification, context.getString(
+ R.string.uninstall_blocked_profile_owner));
+ }
+ }
+ break;
+ }
+ default:
+ Log.d(LOG_TAG, "Uninstall blocked for " + appInfo.packageName
+ + " with legacy code " + legacyStatus);
+ } break;
+ }
+ default:
+ Log.d(LOG_TAG, "Uninstall failed for " + appInfo.packageName + " with code "
+ + returnCode);
+ break;
+ }
+
+ uninstallFailedNotification.setContentTitle(
+ context.getString(R.string.uninstall_failed_app, appLabel));
+ uninstallFailedNotification.setOngoing(false);
+ uninstallFailedNotification.setSmallIcon(R.drawable.ic_error);
+ notificationManager.notify(uninstallId, uninstallFailedNotification.build());
+ }
+
+ /**
+ * Is a profile part of a user?
+ *
+ * @param userManager The user manager
+ * @param userId The id of the user
+ * @param profileId The id of the profile
+ *
+ * @return If the profile is part of the user or the profile parent of the user
+ */
+ private boolean isProfileOfOrSame(@NonNull UserManager userManager, int userId, int profileId) {
+ if (userId == profileId) {
+ return true;
+ }
+
+ UserInfo parentUser = userManager.getProfileParent(profileId);
+ return parentUser != null && parentUser.id == userId;
+ }
+
+ /**
+ * Set big text for the notification.
+ *
+ * @param builder The builder of the notification
+ * @param text The text to set.
+ */
+ private void setBigText(@NonNull Notification.Builder builder,
+ @NonNull CharSequence text) {
+ builder.setStyle(new Notification.BigTextStyle().bigText(text));
+ }
+
+ /**
+ * Add a button to the notification that links to the user management.
+ *
+ * @param context The context the notification is created in
+ * @param builder The builder of the notification
+ */
+ private void addManageUsersButton(@NonNull Context context,
+ @NonNull Notification.Builder builder) {
+ Intent intent = new Intent(Settings.ACTION_USER_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ builder.addAction((new Notification.Action.Builder(
+ Icon.createWithResource(context, R.drawable.ic_settings_multiuser),
+ context.getString(R.string.manage_users),
+ PendingIntent.getActivity(context, 0, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT))).build());
+ }
+
+ /**
+ * Add a button to the notification that links to the device policy management.
+ *
+ * @param context The context the notification is created in
+ * @param builder The builder of the notification
+ */
+ private void addDeviceManagerButton(@NonNull Context context,
+ @NonNull Notification.Builder builder) {
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$DeviceAdminSettingsActivity");
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ builder.addAction((new Notification.Action.Builder(
+ Icon.createWithResource(context, R.drawable.ic_lock),
+ context.getString(R.string.manage_device_administrators),
+ PendingIntent.getActivity(context, 0, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT))).build());
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
new file mode 100644
index 0000000..e27186b
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallUninstalling.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.packageinstaller;
+
+import android.app.Activity;
+import android.app.ActivityThread;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDeleteObserver2;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.VersionedPackage;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import androidx.annotation.Nullable;
+import android.util.Log;
+import android.widget.Toast;
+
+/**
+ * Start an uninstallation, show a dialog while uninstalling and return result to the caller.
+ */
+public class UninstallUninstalling extends Activity implements
+ EventResultPersister.EventResultObserver {
+ private static final String LOG_TAG = UninstallUninstalling.class.getSimpleName();
+
+ private static final String UNINSTALL_ID = "com.android.packageinstaller.UNINSTALL_ID";
+ private static final String BROADCAST_ACTION =
+ "com.android.packageinstaller.ACTION_UNINSTALL_COMMIT";
+
+ static final String EXTRA_APP_LABEL = "com.android.packageinstaller.extra.APP_LABEL";
+
+ private int mUninstallId;
+ private ApplicationInfo mAppInfo;
+ private IBinder mCallback;
+ private boolean mReturnResult;
+ private String mLabel;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setFinishOnTouchOutside(false);
+
+ mAppInfo = getIntent().getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
+ mCallback = getIntent().getIBinderExtra(PackageInstaller.EXTRA_CALLBACK);
+ mReturnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false);
+ mLabel = getIntent().getStringExtra(EXTRA_APP_LABEL);
+
+ try {
+ if (savedInstanceState == null) {
+ boolean allUsers = getIntent().getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS,
+ false);
+ UserHandle user = getIntent().getParcelableExtra(Intent.EXTRA_USER);
+
+ // Show dialog, which is the whole UI
+ FragmentTransaction transaction = getFragmentManager().beginTransaction();
+ Fragment prev = getFragmentManager().findFragmentByTag("dialog");
+ if (prev != null) {
+ transaction.remove(prev);
+ }
+ DialogFragment dialog = new UninstallUninstallingFragment();
+ dialog.setCancelable(false);
+ dialog.show(transaction, "dialog");
+
+ mUninstallId = UninstallEventReceiver.addObserver(this,
+ EventResultPersister.GENERATE_NEW_ID, this);
+
+ Intent broadcastIntent = new Intent(BROADCAST_ACTION);
+ broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ broadcastIntent.putExtra(EventResultPersister.EXTRA_ID, mUninstallId);
+ broadcastIntent.setPackage(getPackageName());
+
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(this, mUninstallId,
+ broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ try {
+ ActivityThread.getPackageManager().getPackageInstaller().uninstall(
+ new VersionedPackage(mAppInfo.packageName,
+ PackageManager.VERSION_CODE_HIGHEST),
+ getPackageName(), allUsers ? PackageManager.DELETE_ALL_USERS : 0,
+ pendingIntent.getIntentSender(), user.getIdentifier());
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ } else {
+ mUninstallId = savedInstanceState.getInt(UNINSTALL_ID);
+ UninstallEventReceiver.addObserver(this, mUninstallId, this);
+ }
+ } catch (EventResultPersister.OutOfIdsException | IllegalArgumentException e) {
+ Log.e(LOG_TAG, "Fails to start uninstall", e);
+ onResult(PackageInstaller.STATUS_FAILURE, PackageManager.DELETE_FAILED_INTERNAL_ERROR,
+ null);
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ outState.putInt(UNINSTALL_ID, mUninstallId);
+ }
+
+ @Override
+ public void onBackPressed() {
+ // do nothing
+ }
+
+ @Override
+ public void onResult(int status, int legacyStatus, @Nullable String message) {
+ if (mCallback != null) {
+ // The caller will be informed about the result via a callback
+ final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub
+ .asInterface(mCallback);
+ try {
+ observer.onPackageDeleted(mAppInfo.packageName, legacyStatus, message);
+ } catch (RemoteException ignored) {
+ }
+ } else if (mReturnResult) {
+ // The caller will be informed about the result and might decide to display it
+ Intent result = new Intent();
+
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, legacyStatus);
+ setResult(status == PackageInstaller.STATUS_SUCCESS ? Activity.RESULT_OK
+ : Activity.RESULT_FIRST_USER, result);
+ } else {
+ // This is the rare case that the caller did not ask for the result, but wanted to be
+ // notified via onActivityResult when the installation finishes
+ if (status != PackageInstaller.STATUS_SUCCESS) {
+ Toast.makeText(this, getString(R.string.uninstall_failed_app, mLabel),
+ Toast.LENGTH_LONG).show();
+ }
+ }
+ finish();
+ }
+
+ @Override
+ protected void onDestroy() {
+ UninstallEventReceiver.removeObserver(this, mUninstallId);
+
+ super.onDestroy();
+ }
+
+ /**
+ * Dialog that shows that the app is uninstalling.
+ */
+ public static class UninstallUninstallingFragment extends DialogFragment {
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
+
+ dialogBuilder.setCancelable(false);
+ dialogBuilder.setMessage(getActivity().getString(R.string.uninstalling_app,
+ ((UninstallUninstalling) getActivity()).mLabel));
+
+ Dialog dialog = dialogBuilder.create();
+ dialog.setCanceledOnTouchOutside(false);
+
+ return dialog;
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
new file mode 100755
index 0000000..d5df9f5
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java
@@ -0,0 +1,395 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package com.android.packageinstaller;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+
+import static com.android.packageinstaller.PackageUtil.getMaxTargetSdkVersionForUid;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.app.AppGlobals;
+import android.app.AppOpsManager;
+import android.app.DialogFragment;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDeleteObserver2;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.VersionedPackage;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import androidx.annotation.NonNull;
+import androidx.annotation.StringRes;
+import android.util.Log;
+
+import com.android.packageinstaller.handheld.ErrorDialogFragment;
+import com.android.packageinstaller.handheld.UninstallAlertDialogFragment;
+import com.android.packageinstaller.television.ErrorFragment;
+import com.android.packageinstaller.television.UninstallAlertFragment;
+import com.android.packageinstaller.television.UninstallAppProgress;
+
+import java.util.List;
+
+/*
+ * This activity presents UI to uninstall an application. Usually launched with intent
+ * Intent.ACTION_UNINSTALL_PKG_COMMAND and attribute
+ * com.android.packageinstaller.PackageName set to the application package name
+ */
+public class UninstallerActivity extends Activity {
+ private static final String TAG = "UninstallerActivity";
+
+ private static final String UNINSTALLING_CHANNEL = "uninstalling";
+
+ public static class DialogInfo {
+ public ApplicationInfo appInfo;
+ public ActivityInfo activityInfo;
+ public boolean allUsers;
+ public UserHandle user;
+ public IBinder callback;
+ }
+
+ private String mPackageName;
+ private DialogInfo mDialogInfo;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ // Never restore any state, esp. never create any fragments. The data in the fragment might
+ // be stale, if e.g. the app was uninstalled while the activity was destroyed.
+ super.onCreate(null);
+
+ try {
+ int callingUid = ActivityManager.getService().getLaunchedFromUid(getActivityToken());
+
+ String callingPackage = getPackageNameForUid(callingUid);
+ if (callingPackage == null) {
+ Log.e(TAG, "Package not found for originating uid " + callingUid);
+ setResult(Activity.RESULT_FIRST_USER);
+ finish();
+ return;
+ } else {
+ AppOpsManager appOpsManager = (AppOpsManager) getSystemService(
+ Context.APP_OPS_SERVICE);
+ if (appOpsManager.noteOpNoThrow(
+ AppOpsManager.OPSTR_REQUEST_DELETE_PACKAGES, callingUid, callingPackage)
+ != MODE_ALLOWED) {
+ Log.e(TAG, "Install from uid " + callingUid + " disallowed by AppOps");
+ setResult(Activity.RESULT_FIRST_USER);
+ finish();
+ return;
+ }
+ }
+
+ if (getMaxTargetSdkVersionForUid(this, callingUid)
+ >= Build.VERSION_CODES.P && AppGlobals.getPackageManager().checkUidPermission(
+ Manifest.permission.REQUEST_DELETE_PACKAGES, callingUid)
+ != PackageManager.PERMISSION_GRANTED
+ && AppGlobals.getPackageManager().checkUidPermission(
+ Manifest.permission.DELETE_PACKAGES, callingUid)
+ != PackageManager.PERMISSION_GRANTED) {
+ Log.e(TAG, "Uid " + callingUid + " does not have "
+ + Manifest.permission.REQUEST_DELETE_PACKAGES + " or "
+ + Manifest.permission.DELETE_PACKAGES);
+
+ setResult(Activity.RESULT_FIRST_USER);
+ finish();
+ return;
+ }
+ } catch (RemoteException ex) {
+ // Cannot reach Package/ActivityManager. Aborting uninstall.
+ Log.e(TAG, "Could not determine the launching uid.");
+
+ setResult(Activity.RESULT_FIRST_USER);
+ finish();
+ return;
+ }
+
+ // Get intent information.
+ // We expect an intent with URI of the form package://<packageName>#<className>
+ // className is optional; if specified, it is the activity the user chose to uninstall
+ final Intent intent = getIntent();
+ final Uri packageUri = intent.getData();
+ if (packageUri == null) {
+ Log.e(TAG, "No package URI in intent");
+ showAppNotFound();
+ return;
+ }
+ mPackageName = packageUri.getEncodedSchemeSpecificPart();
+ if (mPackageName == null) {
+ Log.e(TAG, "Invalid package name in URI: " + packageUri);
+ showAppNotFound();
+ return;
+ }
+
+ final IPackageManager pm = IPackageManager.Stub.asInterface(
+ ServiceManager.getService("package"));
+
+ mDialogInfo = new DialogInfo();
+
+ mDialogInfo.allUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
+ if (mDialogInfo.allUsers && !UserManager.get(this).isAdminUser()) {
+ Log.e(TAG, "Only admin user can request uninstall for all users");
+ showUserIsNotAllowed();
+ return;
+ }
+ mDialogInfo.user = intent.getParcelableExtra(Intent.EXTRA_USER);
+ if (mDialogInfo.user == null) {
+ mDialogInfo.user = android.os.Process.myUserHandle();
+ } else {
+ UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
+ List<UserHandle> profiles = userManager.getUserProfiles();
+ if (!profiles.contains(mDialogInfo.user)) {
+ Log.e(TAG, "User " + android.os.Process.myUserHandle() + " can't request uninstall "
+ + "for user " + mDialogInfo.user);
+ showUserIsNotAllowed();
+ return;
+ }
+ }
+
+ mDialogInfo.callback = intent.getIBinderExtra(PackageInstaller.EXTRA_CALLBACK);
+
+ try {
+ mDialogInfo.appInfo = pm.getApplicationInfo(mPackageName,
+ PackageManager.MATCH_ANY_USER, mDialogInfo.user.getIdentifier());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to get packageName. Package manager is dead?");
+ }
+
+ if (mDialogInfo.appInfo == null) {
+ Log.e(TAG, "Invalid packageName: " + mPackageName);
+ showAppNotFound();
+ return;
+ }
+
+ // The class name may have been specified (e.g. when deleting an app from all apps)
+ final String className = packageUri.getFragment();
+ if (className != null) {
+ try {
+ mDialogInfo.activityInfo = pm.getActivityInfo(
+ new ComponentName(mPackageName, className), 0,
+ mDialogInfo.user.getIdentifier());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to get className. Package manager is dead?");
+ // Continue as the ActivityInfo isn't critical.
+ }
+ }
+
+ showConfirmationDialog();
+ }
+
+ public DialogInfo getDialogInfo() {
+ return mDialogInfo;
+ }
+
+ private void showConfirmationDialog() {
+ if (isTv()) {
+ showContentFragment(new UninstallAlertFragment(), 0, 0);
+ } else {
+ showDialogFragment(new UninstallAlertDialogFragment(), 0, 0);
+ }
+ }
+
+ private void showAppNotFound() {
+ if (isTv()) {
+ showContentFragment(new ErrorFragment(), R.string.app_not_found_dlg_title,
+ R.string.app_not_found_dlg_text);
+ } else {
+ showDialogFragment(new ErrorDialogFragment(), R.string.app_not_found_dlg_title,
+ R.string.app_not_found_dlg_text);
+ }
+ }
+
+ private void showUserIsNotAllowed() {
+ if (isTv()) {
+ showContentFragment(new ErrorFragment(),
+ R.string.user_is_not_allowed_dlg_title, R.string.user_is_not_allowed_dlg_text);
+ } else {
+ showDialogFragment(new ErrorDialogFragment(), 0, R.string.user_is_not_allowed_dlg_text);
+ }
+ }
+
+ private void showGenericError() {
+ if (isTv()) {
+ showContentFragment(new ErrorFragment(),
+ R.string.generic_error_dlg_title, R.string.generic_error_dlg_text);
+ } else {
+ showDialogFragment(new ErrorDialogFragment(), 0, R.string.generic_error_dlg_text);
+ }
+ }
+
+ private boolean isTv() {
+ return (getResources().getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK)
+ == Configuration.UI_MODE_TYPE_TELEVISION;
+ }
+
+ private void showContentFragment(@NonNull Fragment fragment, @StringRes int title,
+ @StringRes int text) {
+ Bundle args = new Bundle();
+ args.putInt(ErrorFragment.TITLE, title);
+ args.putInt(ErrorFragment.TEXT, text);
+ fragment.setArguments(args);
+
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, fragment)
+ .commit();
+ }
+
+ private void showDialogFragment(@NonNull DialogFragment fragment,
+ @StringRes int title, @StringRes int text) {
+ FragmentTransaction ft = getFragmentManager().beginTransaction();
+ Fragment prev = getFragmentManager().findFragmentByTag("dialog");
+ if (prev != null) {
+ ft.remove(prev);
+ }
+
+ Bundle args = new Bundle();
+ if (title != 0) {
+ args.putInt(ErrorDialogFragment.TITLE, title);
+ }
+ args.putInt(ErrorDialogFragment.TEXT, text);
+
+ fragment.setArguments(args);
+ fragment.show(ft, "dialog");
+ }
+
+ public void startUninstallProgress() {
+ boolean returnResult = getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false);
+ CharSequence label = mDialogInfo.appInfo.loadSafeLabel(getPackageManager());
+
+ if (isTv()) {
+ Intent newIntent = new Intent(Intent.ACTION_VIEW);
+ newIntent.putExtra(Intent.EXTRA_USER, mDialogInfo.user);
+ newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers);
+ newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback);
+ newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo);
+
+ if (returnResult) {
+ newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ }
+
+ newIntent.setClass(this, UninstallAppProgress.class);
+ startActivity(newIntent);
+ } else if (returnResult || mDialogInfo.callback != null || getCallingActivity() != null) {
+ Intent newIntent = new Intent(this, UninstallUninstalling.class);
+
+ newIntent.putExtra(Intent.EXTRA_USER, mDialogInfo.user);
+ newIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers);
+ newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo);
+ newIntent.putExtra(UninstallUninstalling.EXTRA_APP_LABEL, label);
+ newIntent.putExtra(PackageInstaller.EXTRA_CALLBACK, mDialogInfo.callback);
+
+ if (returnResult) {
+ newIntent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
+ }
+
+ if (returnResult || getCallingActivity() != null) {
+ newIntent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+ }
+
+ startActivity(newIntent);
+ } else {
+ int uninstallId;
+ try {
+ uninstallId = UninstallEventReceiver.getNewId(this);
+ } catch (EventResultPersister.OutOfIdsException e) {
+ showGenericError();
+ return;
+ }
+
+ Intent broadcastIntent = new Intent(this, UninstallFinish.class);
+
+ broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ broadcastIntent.putExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, mDialogInfo.allUsers);
+ broadcastIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mDialogInfo.appInfo);
+ broadcastIntent.putExtra(UninstallFinish.EXTRA_APP_LABEL, label);
+ broadcastIntent.putExtra(UninstallFinish.EXTRA_UNINSTALL_ID, uninstallId);
+
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(this, uninstallId,
+ broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ NotificationChannel uninstallingChannel = new NotificationChannel(UNINSTALLING_CHANNEL,
+ getString(R.string.uninstalling_notification_channel),
+ NotificationManager.IMPORTANCE_MIN);
+ notificationManager.createNotificationChannel(uninstallingChannel);
+
+ Notification uninstallingNotification =
+ (new Notification.Builder(this, UNINSTALLING_CHANNEL))
+ .setSmallIcon(R.drawable.ic_remove).setProgress(0, 1, true)
+ .setContentTitle(getString(R.string.uninstalling_app, label)).setOngoing(true)
+ .build();
+
+ notificationManager.notify(uninstallId, uninstallingNotification);
+
+ try {
+ Log.i(TAG, "Uninstalling extras=" + broadcastIntent.getExtras());
+
+ ActivityThread.getPackageManager().getPackageInstaller().uninstall(
+ new VersionedPackage(mDialogInfo.appInfo.packageName,
+ PackageManager.VERSION_CODE_HIGHEST),
+ getPackageName(), mDialogInfo.allUsers
+ ? PackageManager.DELETE_ALL_USERS : 0,
+ pendingIntent.getIntentSender(), mDialogInfo.user.getIdentifier());
+ } catch (Exception e) {
+ notificationManager.cancel(uninstallId);
+
+ Log.e(TAG, "Cannot start uninstall", e);
+ showGenericError();
+ }
+ }
+ }
+
+ public void dispatchAborted() {
+ if (mDialogInfo != null && mDialogInfo.callback != null) {
+ final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub.asInterface(
+ mDialogInfo.callback);
+ try {
+ observer.onPackageDeleted(mPackageName,
+ PackageManager.DELETE_FAILED_ABORTED, "Cancelled by user");
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ private String getPackageNameForUid(int sourceUid) {
+ String[] packagesForUid = getPackageManager().getPackagesForUid(sourceUid);
+ if (packagesForUid == null) {
+ return null;
+ }
+ return packagesForUid[0];
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/ErrorDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/ErrorDialogFragment.java
new file mode 100644
index 0000000..4ec6a2d
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/ErrorDialogFragment.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.handheld;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.os.Bundle;
+
+import com.android.packageinstaller.UninstallerActivity;
+
+public class ErrorDialogFragment extends DialogFragment {
+ public static final String TITLE = "com.android.packageinstaller.arg.title";
+ public static final String TEXT = "com.android.packageinstaller.arg.text";
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder b = new AlertDialog.Builder(getActivity())
+ .setMessage(getArguments().getInt(TEXT))
+ .setPositiveButton(android.R.string.ok, null);
+
+ if (getArguments().containsKey(TITLE)) {
+ b.setTitle(getArguments().getInt(TITLE));
+ }
+
+ return b.create();
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ if (isAdded()) {
+ if (getActivity() instanceof UninstallerActivity) {
+ ((UninstallerActivity) getActivity()).dispatchAborted();
+ }
+
+ getActivity().setResult(Activity.RESULT_FIRST_USER);
+ getActivity().finish();
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
new file mode 100644
index 0000000..e0ca74e
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.handheld;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserManager;
+
+import com.android.packageinstaller.R;
+import com.android.packageinstaller.UninstallerActivity;
+
+public class UninstallAlertDialogFragment extends DialogFragment implements
+ DialogInterface.OnClickListener {
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final PackageManager pm = getActivity().getPackageManager();
+ final UninstallerActivity.DialogInfo dialogInfo =
+ ((UninstallerActivity) getActivity()).getDialogInfo();
+ final CharSequence appLabel = dialogInfo.appInfo.loadSafeLabel(pm);
+ AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity());
+ StringBuilder messageBuilder = new StringBuilder();
+
+ // If the Activity label differs from the App label, then make sure the user
+ // knows the Activity belongs to the App being uninstalled.
+ if (dialogInfo.activityInfo != null) {
+ final CharSequence activityLabel = dialogInfo.activityInfo.loadSafeLabel(pm);
+ if (!activityLabel.equals(appLabel)) {
+ messageBuilder.append(
+ getString(R.string.uninstall_activity_text, activityLabel));
+ messageBuilder.append(" ").append(appLabel).append(".\n\n");
+ }
+ }
+
+ final boolean isUpdate =
+ ((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+ UserManager userManager = UserManager.get(getActivity());
+ if (isUpdate) {
+ if (isSingleUser(userManager)) {
+ messageBuilder.append(getString(R.string.uninstall_update_text));
+ } else {
+ messageBuilder.append(getString(R.string.uninstall_update_text_multiuser));
+ }
+ } else {
+ if (dialogInfo.allUsers && !isSingleUser(userManager)) {
+ messageBuilder.append(getString(R.string.uninstall_application_text_all_users));
+ } else if (!dialogInfo.user.equals(android.os.Process.myUserHandle())) {
+ UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier());
+ messageBuilder.append(
+ getString(R.string.uninstall_application_text_user, userInfo.name));
+ } else {
+ messageBuilder.append(getString(R.string.uninstall_application_text));
+ }
+ }
+
+ dialogBuilder.setTitle(appLabel);
+ dialogBuilder.setPositiveButton(android.R.string.ok, this);
+ dialogBuilder.setNegativeButton(android.R.string.cancel, this);
+ dialogBuilder.setMessage(messageBuilder.toString());
+ return dialogBuilder.create();
+ }
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (which == Dialog.BUTTON_POSITIVE) {
+ ((UninstallerActivity) getActivity()).startUninstallProgress();
+ } else {
+ ((UninstallerActivity) getActivity()).dispatchAborted();
+ }
+ }
+
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ super.onDismiss(dialog);
+ if (isAdded()) {
+ getActivity().finish();
+ }
+ }
+
+ /**
+ * Returns whether there is only one user on this device, not including
+ * the system-only user.
+ */
+ private boolean isSingleUser(UserManager userManager) {
+ final int userCount = userManager.getUserCount();
+ return userCount == 1
+ || (UserManager.isSplitSystemUser() && userCount == 2);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/permission/ui/OverlayTouchActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/permission/ui/OverlayTouchActivity.java
new file mode 100644
index 0000000..8aa158b
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/permission/ui/OverlayTouchActivity.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.packageinstaller.permission.ui;
+
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class OverlayTouchActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+ super.onCreate(savedInstanceState);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/ErrorFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/ErrorFragment.java
new file mode 100644
index 0000000..f00f684
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/ErrorFragment.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.television;
+
+import android.app.Activity;
+import android.os.Bundle;
+import androidx.leanback.app.GuidedStepFragment;
+import androidx.leanback.widget.GuidanceStylist;
+import androidx.leanback.widget.GuidedAction;
+
+import com.android.packageinstaller.R;
+import com.android.packageinstaller.UninstallerActivity;
+
+import java.util.List;
+
+public class ErrorFragment extends GuidedStepFragment {
+ public static final String TITLE = "com.android.packageinstaller.arg.title";
+ public static final String TEXT = "com.android.packageinstaller.arg.text";
+
+ @Override
+ public int onProvideTheme() {
+ return R.style.Theme_Leanback_GuidedStep;
+ }
+
+ @Override
+ public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
+ return new GuidanceStylist.Guidance(
+ getString(getArguments().getInt(TITLE)),
+ getString(getArguments().getInt(TEXT)),
+ null,
+ null);
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder(getContext())
+ .clickAction(GuidedAction.ACTION_ID_OK)
+ .build());
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (isAdded()) {
+ if (getActivity() instanceof UninstallerActivity) {
+ ((UninstallerActivity) getActivity()).dispatchAborted();
+ }
+
+ getActivity().setResult(Activity.RESULT_FIRST_USER);
+ getActivity().finish();
+ }
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
new file mode 100644
index 0000000..828e5db
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAlertFragment.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.television;
+
+import android.app.Activity;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.os.Bundle;
+import android.os.UserManager;
+import androidx.leanback.app.GuidedStepFragment;
+import androidx.leanback.widget.GuidanceStylist;
+import androidx.leanback.widget.GuidedAction;
+
+import com.android.packageinstaller.R;
+import com.android.packageinstaller.UninstallerActivity;
+
+import java.util.List;
+
+public class UninstallAlertFragment extends GuidedStepFragment {
+ @Override
+ public int onProvideTheme() {
+ return R.style.Theme_Leanback_GuidedStep;
+ }
+
+ @Override
+ public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
+ final PackageManager pm = getActivity().getPackageManager();
+ final UninstallerActivity.DialogInfo dialogInfo =
+ ((UninstallerActivity) getActivity()).getDialogInfo();
+ final CharSequence appLabel = dialogInfo.appInfo.loadSafeLabel(pm);
+
+ StringBuilder messageBuilder = new StringBuilder();
+
+ // If the Activity label differs from the App label, then make sure the user
+ // knows the Activity belongs to the App being uninstalled.
+ if (dialogInfo.activityInfo != null) {
+ final CharSequence activityLabel = dialogInfo.activityInfo.loadSafeLabel(pm);
+ if (!activityLabel.equals(appLabel)) {
+ messageBuilder.append(
+ getString(R.string.uninstall_activity_text, activityLabel));
+ messageBuilder.append(" ").append(appLabel).append(".\n\n");
+ }
+ }
+
+ final boolean isUpdate =
+ ((dialogInfo.appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+ UserManager userManager = UserManager.get(getActivity());
+ if (isUpdate) {
+ if (isSingleUser(userManager)) {
+ messageBuilder.append(getString(R.string.uninstall_update_text));
+ } else {
+ messageBuilder.append(getString(R.string.uninstall_update_text_multiuser));
+ }
+ } else {
+ if (dialogInfo.allUsers && !isSingleUser(userManager)) {
+ messageBuilder.append(getString(R.string.uninstall_application_text_all_users));
+ } else if (!dialogInfo.user.equals(android.os.Process.myUserHandle())) {
+ UserInfo userInfo = userManager.getUserInfo(dialogInfo.user.getIdentifier());
+ messageBuilder.append(
+ getString(R.string.uninstall_application_text_user, userInfo.name));
+ } else {
+ messageBuilder.append(getString(R.string.uninstall_application_text));
+ }
+ }
+
+ return new GuidanceStylist.Guidance(
+ appLabel.toString(),
+ messageBuilder.toString(),
+ null,
+ dialogInfo.appInfo.loadIcon(pm));
+ }
+
+ @Override
+ public void onCreateActions(List<GuidedAction> actions, Bundle savedInstanceState) {
+ actions.add(new GuidedAction.Builder(getContext())
+ .clickAction(GuidedAction.ACTION_ID_OK)
+ .build());
+ actions.add(new GuidedAction.Builder(getContext())
+ .clickAction(GuidedAction.ACTION_ID_CANCEL)
+ .build());
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (isAdded()) {
+ if (action.getId() == GuidedAction.ACTION_ID_OK) {
+ ((UninstallerActivity) getActivity()).startUninstallProgress();
+ getActivity().finish();
+ } else {
+ ((UninstallerActivity) getActivity()).dispatchAborted();
+ getActivity().setResult(Activity.RESULT_FIRST_USER);
+ getActivity().finish();
+ }
+ }
+ }
+
+ /**
+ * Returns whether there is only one user on this device, not including
+ * the system-only user.
+ */
+ private boolean isSingleUser(UserManager userManager) {
+ final int userCount = userManager.getUserCount();
+ return userCount == 1
+ || (UserManager.isSplitSystemUser() && userCount == 2);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgress.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgress.java
new file mode 100755
index 0000000..a4f217c
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgress.java
@@ -0,0 +1,377 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+package com.android.packageinstaller.television;
+
+import android.app.Activity;
+import android.app.admin.IDevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.IPackageDeleteObserver2;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.content.pm.UserInfo;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.KeyEvent;
+import android.widget.Toast;
+
+import com.android.packageinstaller.PackageUtil;
+import com.android.packageinstaller.R;
+
+import java.lang.ref.WeakReference;
+import java.util.List;
+
+/**
+ * This activity corresponds to a download progress screen that is displayed
+ * when an application is uninstalled. The result of the application uninstall
+ * is indicated in the result code that gets set to 0 or 1. The application gets launched
+ * by an intent with the intent's class name explicitly set to UninstallAppProgress and expects
+ * the application object of the application to uninstall.
+ */
+public class UninstallAppProgress extends Activity {
+ private static final String TAG = "UninstallAppProgress";
+
+ private static final String FRAGMENT_TAG = "progress_fragment";
+
+ private ApplicationInfo mAppInfo;
+ private boolean mAllUsers;
+ private IBinder mCallback;
+
+ private volatile int mResultCode = -1;
+
+ /**
+ * If initView was called. We delay this call to not have to call it at all if the uninstall is
+ * quick
+ */
+ private boolean mIsViewInitialized;
+
+ /** Amount of time to wait until we show the UI */
+ private static final int QUICK_INSTALL_DELAY_MILLIS = 500;
+
+ private static final int UNINSTALL_COMPLETE = 1;
+ private static final int UNINSTALL_IS_SLOW = 2;
+
+ private Handler mHandler = new MessageHandler(this);
+
+ private static class MessageHandler extends Handler {
+ private final WeakReference<UninstallAppProgress> mActivity;
+
+ public MessageHandler(UninstallAppProgress activity) {
+ mActivity = new WeakReference<>(activity);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ UninstallAppProgress activity = mActivity.get();
+ if (activity != null) {
+ activity.handleMessage(msg);
+ }
+ }
+ }
+
+ private void handleMessage(Message msg) {
+ if (isFinishing() || isDestroyed()) {
+ return;
+ }
+
+ switch (msg.what) {
+ case UNINSTALL_IS_SLOW:
+ initView();
+ break;
+ case UNINSTALL_COMPLETE:
+ mHandler.removeMessages(UNINSTALL_IS_SLOW);
+
+ if (msg.arg1 != PackageManager.DELETE_SUCCEEDED) {
+ initView();
+ }
+
+ mResultCode = msg.arg1;
+ final String packageName = (String) msg.obj;
+
+ if (mCallback != null) {
+ final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub
+ .asInterface(mCallback);
+ try {
+ observer.onPackageDeleted(mAppInfo.packageName, mResultCode,
+ packageName);
+ } catch (RemoteException ignored) {
+ }
+ finish();
+ return;
+ }
+
+ if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false)) {
+ Intent result = new Intent();
+ result.putExtra(Intent.EXTRA_INSTALL_RESULT, mResultCode);
+ setResult(mResultCode == PackageManager.DELETE_SUCCEEDED
+ ? Activity.RESULT_OK : Activity.RESULT_FIRST_USER,
+ result);
+ finish();
+ return;
+ }
+
+ // Update the status text
+ final String statusText;
+ switch (msg.arg1) {
+ case PackageManager.DELETE_SUCCEEDED:
+ statusText = getString(R.string.uninstall_done);
+ // Show a Toast and finish the activity
+ Context ctx = getBaseContext();
+ Toast.makeText(ctx, statusText, Toast.LENGTH_LONG).show();
+ setResultAndFinish();
+ return;
+ case PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER: {
+ UserManager userManager =
+ (UserManager) getSystemService(Context.USER_SERVICE);
+ IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
+ ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
+ // Find out if the package is an active admin for some non-current user.
+ int myUserId = UserHandle.myUserId();
+ UserInfo otherBlockingUser = null;
+ for (UserInfo user : userManager.getUsers()) {
+ // We only catch the case when the user in question is neither the
+ // current user nor its profile.
+ if (isProfileOfOrSame(userManager, myUserId, user.id)) continue;
+
+ try {
+ if (dpm.packageHasActiveAdmins(packageName, user.id)) {
+ otherBlockingUser = user;
+ break;
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to talk to package manager", e);
+ }
+ }
+ if (otherBlockingUser == null) {
+ Log.d(TAG, "Uninstall failed because " + packageName
+ + " is a device admin");
+ getProgressFragment().setDeviceManagerButtonVisible(true);
+ statusText = getString(
+ R.string.uninstall_failed_device_policy_manager);
+ } else {
+ Log.d(TAG, "Uninstall failed because " + packageName
+ + " is a device admin of user " + otherBlockingUser);
+ getProgressFragment().setDeviceManagerButtonVisible(false);
+ statusText = String.format(
+ getString(R.string.uninstall_failed_device_policy_manager_of_user),
+ otherBlockingUser.name);
+ }
+ break;
+ }
+ case PackageManager.DELETE_FAILED_OWNER_BLOCKED: {
+ UserManager userManager =
+ (UserManager) getSystemService(Context.USER_SERVICE);
+ IPackageManager packageManager = IPackageManager.Stub.asInterface(
+ ServiceManager.getService("package"));
+ List<UserInfo> users = userManager.getUsers();
+ int blockingUserId = UserHandle.USER_NULL;
+ for (int i = 0; i < users.size(); ++i) {
+ final UserInfo user = users.get(i);
+ try {
+ if (packageManager.getBlockUninstallForUser(packageName,
+ user.id)) {
+ blockingUserId = user.id;
+ break;
+ }
+ } catch (RemoteException e) {
+ // Shouldn't happen.
+ Log.e(TAG, "Failed to talk to package manager", e);
+ }
+ }
+ int myUserId = UserHandle.myUserId();
+ if (isProfileOfOrSame(userManager, myUserId, blockingUserId)) {
+ getProgressFragment().setDeviceManagerButtonVisible(true);
+ } else {
+ getProgressFragment().setDeviceManagerButtonVisible(false);
+ getProgressFragment().setUsersButtonVisible(true);
+ }
+ // TODO: b/25442806
+ if (blockingUserId == UserHandle.USER_SYSTEM) {
+ statusText = getString(R.string.uninstall_blocked_device_owner);
+ } else if (blockingUserId == UserHandle.USER_NULL) {
+ Log.d(TAG, "Uninstall failed for " + packageName + " with code "
+ + msg.arg1 + " no blocking user");
+ statusText = getString(R.string.uninstall_failed);
+ } else {
+ statusText = mAllUsers
+ ? getString(R.string.uninstall_all_blocked_profile_owner) :
+ getString(R.string.uninstall_blocked_profile_owner);
+ }
+ break;
+ }
+ default:
+ Log.d(TAG, "Uninstall failed for " + packageName + " with code "
+ + msg.arg1);
+ statusText = getString(R.string.uninstall_failed);
+ break;
+ }
+ getProgressFragment().showCompletion(statusText);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private boolean isProfileOfOrSame(UserManager userManager, int userId, int profileId) {
+ if (userId == profileId) {
+ return true;
+ }
+ UserInfo parentUser = userManager.getProfileParent(profileId);
+ return parentUser != null && parentUser.id == userId;
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ Intent intent = getIntent();
+ mAppInfo = intent.getParcelableExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO);
+ mCallback = intent.getIBinderExtra(PackageInstaller.EXTRA_CALLBACK);
+
+ // This currently does not support going through a onDestroy->onCreate cycle. Hence if that
+ // happened, just fail the operation for mysterious reasons.
+ if (icicle != null) {
+ mResultCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
+
+ if (mCallback != null) {
+ final IPackageDeleteObserver2 observer = IPackageDeleteObserver2.Stub
+ .asInterface(mCallback);
+ try {
+ observer.onPackageDeleted(mAppInfo.packageName, mResultCode, null);
+ } catch (RemoteException ignored) {
+ }
+ finish();
+ } else {
+ setResultAndFinish();
+ }
+
+ return;
+ }
+
+ mAllUsers = intent.getBooleanExtra(Intent.EXTRA_UNINSTALL_ALL_USERS, false);
+ UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
+ if (user == null) {
+ user = android.os.Process.myUserHandle();
+ }
+
+ PackageDeleteObserver observer = new PackageDeleteObserver();
+
+ // Make window transparent until initView is called. In many cases we can avoid showing the
+ // UI at all as the app is uninstalled very quickly. If we show the UI and instantly remove
+ // it, it just looks like a flicker.
+ getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
+ getWindow().setStatusBarColor(Color.TRANSPARENT);
+ getWindow().setNavigationBarColor(Color.TRANSPARENT);
+
+ try {
+ getPackageManager().deletePackageAsUser(mAppInfo.packageName, observer,
+ mAllUsers ? PackageManager.DELETE_ALL_USERS : 0, user.getIdentifier());
+ } catch (IllegalArgumentException e) {
+ // Couldn't find the package, no need to call uninstall.
+ Log.w(TAG, "Could not find package, not deleting " + mAppInfo.packageName, e);
+ }
+
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(UNINSTALL_IS_SLOW),
+ QUICK_INSTALL_DELAY_MILLIS);
+ }
+
+ public ApplicationInfo getAppInfo() {
+ return mAppInfo;
+ }
+
+ private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
+ public void packageDeleted(String packageName, int returnCode) {
+ Message msg = mHandler.obtainMessage(UNINSTALL_COMPLETE);
+ msg.arg1 = returnCode;
+ msg.obj = packageName;
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ public void setResultAndFinish() {
+ setResult(mResultCode);
+ finish();
+ }
+
+ private void initView() {
+ if (mIsViewInitialized) {
+ return;
+ }
+ mIsViewInitialized = true;
+
+ // We set the window background to translucent in constructor, revert this
+ TypedValue attribute = new TypedValue();
+ getTheme().resolveAttribute(android.R.attr.windowBackground, attribute, true);
+ if (attribute.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
+ attribute.type <= TypedValue.TYPE_LAST_COLOR_INT) {
+ getWindow().setBackgroundDrawable(new ColorDrawable(attribute.data));
+ } else {
+ getWindow().setBackgroundDrawable(getResources().getDrawable(attribute.resourceId,
+ getTheme()));
+ }
+
+ getTheme().resolveAttribute(android.R.attr.navigationBarColor, attribute, true);
+ getWindow().setNavigationBarColor(attribute.data);
+
+ getTheme().resolveAttribute(android.R.attr.statusBarColor, attribute, true);
+ getWindow().setStatusBarColor(attribute.data);
+
+ boolean isUpdate = ((mAppInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0);
+ setTitle(isUpdate ? R.string.uninstall_update_title : R.string.uninstall_application_title);
+
+ getFragmentManager().beginTransaction()
+ .add(android.R.id.content, new UninstallAppProgressFragment(), FRAGMENT_TAG)
+ .commitNowAllowingStateLoss();
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent ev) {
+ if (ev.getKeyCode() == KeyEvent.KEYCODE_BACK) {
+ if (mResultCode == -1) {
+ // Ignore back key when installation is in progress
+ return true;
+ } else {
+ // If installation is done, just set the result code
+ setResult(mResultCode);
+ }
+ }
+ return super.dispatchKeyEvent(ev);
+ }
+
+ private ProgressFragment getProgressFragment() {
+ return (ProgressFragment) getFragmentManager().findFragmentByTag(FRAGMENT_TAG);
+ }
+
+ public interface ProgressFragment {
+ void setUsersButtonVisible(boolean visible);
+ void setDeviceManagerButtonVisible(boolean visible);
+ void showCompletion(CharSequence statusText);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java
new file mode 100644
index 0000000..7402a7d
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/television/UninstallAppProgressFragment.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.television;
+
+import android.app.Fragment;
+import android.content.Intent;
+import android.os.Bundle;
+import android.provider.Settings;
+import androidx.annotation.Nullable;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.packageinstaller.PackageUtil;
+import com.android.packageinstaller.R;
+
+public class UninstallAppProgressFragment extends Fragment implements View.OnClickListener,
+ UninstallAppProgress.ProgressFragment {
+ private static final String TAG = "UninstallAppProgressF"; // full class name is too long
+
+ private Button mOkButton;
+ private Button mDeviceManagerButton;
+ private Button mUsersButton;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
+ Bundle savedInstanceState) {
+ final View root = inflater.inflate(R.layout.uninstall_progress, container, false);
+ // Initialize views
+ View snippetView = root.findViewById(R.id.app_snippet);
+ PackageUtil.initSnippetForInstalledApp(getContext(),
+ ((UninstallAppProgress)getActivity()).getAppInfo(), snippetView);
+ mDeviceManagerButton = (Button) root.findViewById(R.id.device_manager_button);
+ mUsersButton = (Button) root.findViewById(R.id.users_button);
+ mDeviceManagerButton.setVisibility(View.GONE);
+ mDeviceManagerButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent();
+ intent.setClassName("com.android.settings",
+ "com.android.settings.Settings$DeviceAdminSettingsActivity");
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ getActivity().finish();
+ }
+ });
+ mUsersButton.setVisibility(View.GONE);
+ mUsersButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Intent intent = new Intent(Settings.ACTION_USER_SETTINGS);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ getActivity().finish();
+ }
+ });
+ // Hide button till progress is being displayed
+ mOkButton = (Button) root.findViewById(R.id.ok_button);
+ mOkButton.setOnClickListener(this);
+
+ return root;
+ }
+
+ public void onClick(View v) {
+ final UninstallAppProgress activity = (UninstallAppProgress) getActivity();
+ if(v == mOkButton && activity != null) {
+ Log.i(TAG, "Finished uninstalling pkg: " +
+ activity.getAppInfo().packageName);
+ activity.setResultAndFinish();
+ }
+ }
+
+ @Override
+ public void setUsersButtonVisible(boolean visible) {
+ mUsersButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+
+ @Override
+ public void setDeviceManagerButtonVisible(boolean visible) {
+ mDeviceManagerButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+
+ @Override
+ public void showCompletion(CharSequence statusText) {
+ final View root = getView();
+ root.findViewById(R.id.progress_view).setVisibility(View.GONE);
+ root.findViewById(R.id.status_view).setVisibility(View.VISIBLE);
+ ((TextView) root.findViewById(R.id.status_text)).setText(statusText);
+ root.findViewById(R.id.ok_panel).setVisibility(View.VISIBLE);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
new file mode 100644
index 0000000..53a460d
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallTask.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+import android.content.Context;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Task that installs an APK. This must not be called on the main thread.
+ * This code is based off the Finsky/Wearsky implementation
+ */
+public class InstallTask {
+ private static final String TAG = "InstallTask";
+
+ private static final int DEFAULT_BUFFER_SIZE = 8192;
+
+ private final Context mContext;
+ private String mPackageName;
+ private ParcelFileDescriptor mParcelFileDescriptor;
+ private PackageInstallerImpl.InstallListener mCallback;
+ private PackageInstaller.Session mSession;
+ private IntentSender mCommitCallback;
+
+ private Exception mException = null;
+ private int mErrorCode = 0;
+ private String mErrorDesc = null;
+
+ public InstallTask(Context context, String packageName,
+ ParcelFileDescriptor parcelFileDescriptor,
+ PackageInstallerImpl.InstallListener callback, PackageInstaller.Session session,
+ IntentSender commitCallback) {
+ mContext = context;
+ mPackageName = packageName;
+ mParcelFileDescriptor = parcelFileDescriptor;
+ mCallback = callback;
+ mSession = session;
+ mCommitCallback = commitCallback;
+ }
+
+ public boolean isError() {
+ return mErrorCode != InstallerConstants.STATUS_SUCCESS || !TextUtils.isEmpty(mErrorDesc);
+ }
+
+ public void execute() {
+ if (Looper.myLooper() == Looper.getMainLooper()) {
+ throw new IllegalStateException("This method cannot be called from the UI thread.");
+ }
+
+ OutputStream sessionStream = null;
+ try {
+ sessionStream = mSession.openWrite(mPackageName, 0, -1);
+
+ // 2b: Stream the asset to the installer. Note:
+ // Note: writeToOutputStreamFromAsset() always safely closes the input stream
+ writeToOutputStreamFromAsset(sessionStream);
+ mSession.fsync(sessionStream);
+ } catch (Exception e) {
+ mException = e;
+ mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM;
+ mErrorDesc = "Could not write to stream";
+ } finally {
+ if (sessionStream != null) {
+ // 2c: close output stream
+ try {
+ sessionStream.close();
+ } catch (Exception e) {
+ // Ignore otherwise
+ if (mException == null) {
+ mException = e;
+ mErrorCode = InstallerConstants.ERROR_INSTALL_CLOSE_STREAM;
+ mErrorDesc = "Could not close session stream";
+ }
+ }
+ }
+ }
+
+ if (mErrorCode != InstallerConstants.STATUS_SUCCESS) {
+ // An error occurred, we're done
+ Log.e(TAG, "Exception while installing " + mPackageName + ": " + mErrorCode + ", "
+ + mErrorDesc + ", " + mException);
+ mSession.close();
+ mCallback.installFailed(mErrorCode, "[" + mPackageName + "]" + mErrorDesc);
+ } else {
+ // 3. Commit the session (this actually installs it.) Session map
+ // will be cleaned up in the callback.
+ mCallback.installBeginning();
+ mSession.commit(mCommitCallback);
+ mSession.close();
+ }
+ }
+
+ /**
+ * {@code PackageInstaller} works with streams. Get the {@code FileDescriptor}
+ * corresponding to the {@code Asset} and then write the contents into an
+ * {@code OutputStream} that is passed in.
+ * <br>
+ * The {@code FileDescriptor} is closed but the {@code OutputStream} is not closed.
+ */
+ private boolean writeToOutputStreamFromAsset(OutputStream outputStream) {
+ if (outputStream == null) {
+ mErrorCode = InstallerConstants.ERROR_INSTALL_COPY_STREAM_EXCEPTION;
+ mErrorDesc = "Got a null OutputStream.";
+ return false;
+ }
+
+ if (mParcelFileDescriptor == null || mParcelFileDescriptor.getFileDescriptor() == null) {
+ mErrorCode = InstallerConstants.ERROR_COULD_NOT_GET_FD;
+ mErrorDesc = "Could not get FD";
+ return false;
+ }
+
+ InputStream inputStream = null;
+ try {
+ byte[] inputBuf = new byte[DEFAULT_BUFFER_SIZE];
+ int bytesRead;
+ inputStream = new ParcelFileDescriptor.AutoCloseInputStream(mParcelFileDescriptor);
+
+ while ((bytesRead = inputStream.read(inputBuf)) > -1) {
+ if (bytesRead > 0) {
+ outputStream.write(inputBuf, 0, bytesRead);
+ }
+ }
+
+ outputStream.flush();
+ } catch (IOException e) {
+ mErrorCode = InstallerConstants.ERROR_INSTALL_APK_COPY_FAILURE;
+ mErrorDesc = "Reading from Asset FD or writing to temp file failed: " + e;
+ return false;
+ } finally {
+ safeClose(inputStream);
+ }
+
+ return true;
+ }
+
+ /**
+ * Quietly close a closeable resource (e.g. a stream or file). The input may already
+ * be closed and it may even be null.
+ */
+ public static void safeClose(Closeable resource) {
+ if (resource != null) {
+ try {
+ resource.close();
+ } catch (IOException ioe) {
+ // Catch and discard the error
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
new file mode 100644
index 0000000..3daf3d8
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/InstallerConstants.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+/**
+ * Constants for Installation / Uninstallation requests.
+ * Using the same values as Finsky/Wearsky code for consistency in user analytics of failures
+ */
+public class InstallerConstants {
+ /** Request succeeded */
+ public static final int STATUS_SUCCESS = 0;
+
+ /**
+ * The new PackageInstaller also returns a small set of less granular error codes, which
+ * we'll remap to the range -500 and below to keep away from existing installer codes
+ * (which run from -1 to -110).
+ */
+ public final static int ERROR_PACKAGEINSTALLER_BASE = -500;
+
+ public static final int ERROR_COULD_NOT_GET_FD = -603;
+ /** This node is not targeted by this request. */
+
+ /** The install did not complete because could not create PackageInstaller session */
+ public final static int ERROR_INSTALL_CREATE_SESSION = -612;
+ /** The install did not complete because could not open PackageInstaller session */
+ public final static int ERROR_INSTALL_OPEN_SESSION = -613;
+ /** The install did not complete because could not open PackageInstaller output stream */
+ public final static int ERROR_INSTALL_OPEN_STREAM = -614;
+ /** The install did not complete because of an exception while streaming bytes */
+ public final static int ERROR_INSTALL_COPY_STREAM_EXCEPTION = -615;
+ /** The install did not complete because of an unexpected exception from PackageInstaller */
+ public final static int ERROR_INSTALL_SESSION_EXCEPTION = -616;
+ /** The install did not complete because of an unexpected userActionRequired callback */
+ public final static int ERROR_INSTALL_USER_ACTION_REQUIRED = -617;
+ /** The install did not complete because of an unexpected broadcast (missing fields) */
+ public final static int ERROR_INSTALL_MALFORMED_BROADCAST = -618;
+ /** The install did not complete because of an error while copying from downloaded file */
+ public final static int ERROR_INSTALL_APK_COPY_FAILURE = -619;
+ /** The install did not complete because of an error while copying to the PackageInstaller
+ * output stream */
+ public final static int ERROR_INSTALL_COPY_STREAM = -620;
+ /** The install did not complete because of an error while closing the PackageInstaller
+ * output stream */
+ public final static int ERROR_INSTALL_CLOSE_STREAM = -621;
+}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
new file mode 100644
index 0000000..bdc22cf
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+import android.content.Context;
+
+/**
+ * Factory that creates a Package Installer.
+ */
+public class PackageInstallerFactory {
+ private static PackageInstallerImpl sPackageInstaller;
+
+ /**
+ * Return the PackageInstaller shared object. {@code init} should have already been called.
+ */
+ public synchronized static PackageInstallerImpl getPackageInstaller(Context context) {
+ if (sPackageInstaller == null) {
+ sPackageInstaller = new PackageInstallerImpl(context);
+ }
+ return sPackageInstaller;
+ }
+}
\ No newline at end of file
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
new file mode 100644
index 0000000..bf4b03c
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/PackageInstallerImpl.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+import android.annotation.TargetApi;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Implementation of package manager installation using modern PackageInstaller api.
+ *
+ * Heavily copied from Wearsky/Finsky implementation
+ */
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
+public class PackageInstallerImpl {
+ private static final String TAG = "PackageInstallerImpl";
+
+ /** Intent actions used for broadcasts from PackageInstaller back to the local receiver */
+ private static final String ACTION_INSTALL_COMMIT =
+ "com.android.vending.INTENT_PACKAGE_INSTALL_COMMIT";
+
+ private final Context mContext;
+ private final PackageInstaller mPackageInstaller;
+ private final Map<String, PackageInstaller.SessionInfo> mSessionInfoMap;
+ private final Map<String, PackageInstaller.Session> mOpenSessionMap;
+
+ public PackageInstallerImpl(Context context) {
+ mContext = context.getApplicationContext();
+ mPackageInstaller = mContext.getPackageManager().getPackageInstaller();
+
+ // Capture a map of known sessions
+ // This list will be pruned a bit later (stale sessions will be canceled)
+ mSessionInfoMap = new HashMap<String, PackageInstaller.SessionInfo>();
+ List<PackageInstaller.SessionInfo> mySessions = mPackageInstaller.getMySessions();
+ for (int i = 0; i < mySessions.size(); i++) {
+ PackageInstaller.SessionInfo sessionInfo = mySessions.get(i);
+ String packageName = sessionInfo.getAppPackageName();
+ PackageInstaller.SessionInfo oldInfo = mSessionInfoMap.put(packageName, sessionInfo);
+
+ // Checking for old info is strictly for logging purposes
+ if (oldInfo != null) {
+ Log.w(TAG, "Multiple sessions for " + packageName + " found. Removing " + oldInfo
+ .getSessionId() + " & keeping " + mySessions.get(i).getSessionId());
+ }
+ }
+ mOpenSessionMap = new HashMap<String, PackageInstaller.Session>();
+ }
+
+ /**
+ * This callback will be made after an installation attempt succeeds or fails.
+ */
+ public interface InstallListener {
+ /**
+ * This callback signals that preflight checks have succeeded and installation
+ * is beginning.
+ */
+ void installBeginning();
+
+ /**
+ * This callback signals that installation has completed.
+ */
+ void installSucceeded();
+
+ /**
+ * This callback signals that installation has failed.
+ */
+ void installFailed(int errorCode, String errorDesc);
+ }
+
+ /**
+ * This is a placeholder implementation that bundles an entire "session" into a single
+ * call. This will be replaced by more granular versions that allow longer session lifetimes,
+ * download progress tracking, etc.
+ *
+ * This must not be called on main thread.
+ */
+ public void install(final String packageName, ParcelFileDescriptor parcelFileDescriptor,
+ final InstallListener callback) {
+ // 0. Generic try/catch block because I am not really sure what exceptions (other than
+ // IOException) might be thrown by PackageInstaller and I want to handle them
+ // at least slightly gracefully.
+ try {
+ // 1. Create or recover a session, and open it
+ // Try recovery first
+ PackageInstaller.Session session = null;
+ PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
+ if (sessionInfo != null) {
+ // See if it's openable, or already held open
+ session = getSession(packageName);
+ }
+ // If open failed, or there was no session, create a new one and open it.
+ // If we cannot create or open here, the failure is terminal.
+ if (session == null) {
+ try {
+ innerCreateSession(packageName);
+ } catch (IOException ioe) {
+ Log.e(TAG, "Can't create session for " + packageName + ": " + ioe.getMessage());
+ callback.installFailed(InstallerConstants.ERROR_INSTALL_CREATE_SESSION,
+ "Could not create session");
+ mSessionInfoMap.remove(packageName);
+ return;
+ }
+ sessionInfo = mSessionInfoMap.get(packageName);
+ try {
+ session = mPackageInstaller.openSession(sessionInfo.getSessionId());
+ mOpenSessionMap.put(packageName, session);
+ } catch (SecurityException se) {
+ Log.e(TAG, "Can't open session for " + packageName + ": " + se.getMessage());
+ callback.installFailed(InstallerConstants.ERROR_INSTALL_OPEN_SESSION,
+ "Can't open session");
+ mSessionInfoMap.remove(packageName);
+ return;
+ }
+ }
+
+ // 2. Launch task to handle file operations.
+ InstallTask task = new InstallTask( mContext, packageName, parcelFileDescriptor,
+ callback, session,
+ getCommitCallback(packageName, sessionInfo.getSessionId(), callback));
+ task.execute();
+ if (task.isError()) {
+ cancelSession(sessionInfo.getSessionId(), packageName);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Unexpected exception while installing: " + packageName + ": "
+ + e.getMessage());
+ callback.installFailed(InstallerConstants.ERROR_INSTALL_SESSION_EXCEPTION,
+ "Unexpected exception while installing " + packageName);
+ }
+ }
+
+ /**
+ * Retrieve an existing session. Will open if needed, but does not attempt to create.
+ */
+ private PackageInstaller.Session getSession(String packageName) {
+ // Check for already-open session
+ PackageInstaller.Session session = mOpenSessionMap.get(packageName);
+ if (session != null) {
+ try {
+ // Probe the session to ensure that it's still open. This may or may not
+ // throw (if non-open), but it may serve as a canary for stale sessions.
+ session.getNames();
+ return session;
+ } catch (IOException ioe) {
+ Log.e(TAG, "Stale open session for " + packageName + ": " + ioe.getMessage());
+ mOpenSessionMap.remove(packageName);
+ } catch (SecurityException se) {
+ Log.e(TAG, "Stale open session for " + packageName + ": " + se.getMessage());
+ mOpenSessionMap.remove(packageName);
+ }
+ }
+ // Check to see if this is a known session
+ PackageInstaller.SessionInfo sessionInfo = mSessionInfoMap.get(packageName);
+ if (sessionInfo == null) {
+ return null;
+ }
+ // Try to open it. If we fail here, assume that the SessionInfo was stale.
+ try {
+ session = mPackageInstaller.openSession(sessionInfo.getSessionId());
+ } catch (SecurityException se) {
+ Log.w(TAG, "SessionInfo was stale for " + packageName + " - deleting info");
+ mSessionInfoMap.remove(packageName);
+ return null;
+ } catch (IOException ioe) {
+ Log.w(TAG, "IOException opening old session for " + ioe.getMessage()
+ + " - deleting info");
+ mSessionInfoMap.remove(packageName);
+ return null;
+ }
+ mOpenSessionMap.put(packageName, session);
+ return session;
+ }
+
+ /** This version throws an IOException when the session cannot be created */
+ private void innerCreateSession(String packageName) throws IOException {
+ if (mSessionInfoMap.containsKey(packageName)) {
+ Log.w(TAG, "Creating session for " + packageName + " when one already exists");
+ return;
+ }
+ PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
+ PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+ params.setAppPackageName(packageName);
+
+ // IOException may be thrown at this point
+ int sessionId = mPackageInstaller.createSession(params);
+ PackageInstaller.SessionInfo sessionInfo = mPackageInstaller.getSessionInfo(sessionId);
+ mSessionInfoMap.put(packageName, sessionInfo);
+ }
+
+ /**
+ * Cancel a session based on its sessionId. Package name is for logging only.
+ */
+ private void cancelSession(int sessionId, String packageName) {
+ // Close if currently held open
+ closeSession(packageName);
+ // Remove local record
+ mSessionInfoMap.remove(packageName);
+ try {
+ mPackageInstaller.abandonSession(sessionId);
+ } catch (SecurityException se) {
+ // The session no longer exists, so we can exit quietly.
+ return;
+ }
+ }
+
+ /**
+ * Close a session if it happens to be held open.
+ */
+ private void closeSession(String packageName) {
+ PackageInstaller.Session session = mOpenSessionMap.remove(packageName);
+ if (session != null) {
+ // Unfortunately close() is not idempotent. Try our best to make this safe.
+ try {
+ session.close();
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error closing session for " + packageName + ": "
+ + e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Creates a commit callback for the package install that's underway. This will be called
+ * some time after calling session.commit() (above).
+ */
+ private IntentSender getCommitCallback(final String packageName, final int sessionId,
+ final InstallListener callback) {
+ // Create a single-use broadcast receiver
+ BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mContext.unregisterReceiver(this);
+ handleCommitCallback(intent, packageName, sessionId, callback);
+ }
+ };
+ // Create a matching intent-filter and register the receiver
+ String action = ACTION_INSTALL_COMMIT + "." + packageName;
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(action);
+ mContext.registerReceiver(broadcastReceiver, intentFilter);
+
+ // Create a matching PendingIntent and use it to generate the IntentSender
+ Intent broadcastIntent = new Intent(action);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, packageName.hashCode(),
+ broadcastIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT);
+ return pendingIntent.getIntentSender();
+ }
+
+ /**
+ * Examine the extras to determine information about the package update/install, decode
+ * the result, and call the appropriate callback.
+ *
+ * @param intent The intent, which the PackageInstaller will have added Extras to
+ * @param packageName The package name we created the receiver for
+ * @param sessionId The session Id we created the receiver for
+ * @param callback The callback to report success/failure to
+ */
+ private void handleCommitCallback(Intent intent, String packageName, int sessionId,
+ InstallListener callback) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Installation of " + packageName + " finished with extras "
+ + intent.getExtras());
+ }
+ String statusMessage = intent.getStringExtra(PackageInstaller.EXTRA_STATUS_MESSAGE);
+ int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS, Integer.MIN_VALUE);
+ if (status == PackageInstaller.STATUS_SUCCESS) {
+ cancelSession(sessionId, packageName);
+ callback.installSucceeded();
+ } else if (status == -1 /*PackageInstaller.STATUS_USER_ACTION_REQUIRED*/) {
+ // TODO - use the constant when the correct/final name is in the SDK
+ // TODO This is unexpected, so we are treating as failure for now
+ cancelSession(sessionId, packageName);
+ callback.installFailed(InstallerConstants.ERROR_INSTALL_USER_ACTION_REQUIRED,
+ "Unexpected: user action required");
+ } else {
+ cancelSession(sessionId, packageName);
+ int errorCode = getPackageManagerErrorCode(status);
+ Log.e(TAG, "Error " + errorCode + " while installing " + packageName + ": "
+ + statusMessage);
+ callback.installFailed(errorCode, null);
+ }
+ }
+
+ private int getPackageManagerErrorCode(int status) {
+ // This is a hack: because PackageInstaller now reports error codes
+ // with small positive values, we need to remap them into a space
+ // that is more compatible with the existing package manager error codes.
+ // See https://sites.google.com/a/google.com/universal-store/documentation
+ // /android-client/download-error-codes
+ int errorCode;
+ if (status == Integer.MIN_VALUE) {
+ errorCode = InstallerConstants.ERROR_INSTALL_MALFORMED_BROADCAST;
+ } else {
+ errorCode = InstallerConstants.ERROR_PACKAGEINSTALLER_BASE - status;
+ }
+ return errorCode;
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
new file mode 100644
index 0000000..2c289b2
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageArgs.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * Installation Util that contains a list of parameters that are needed for
+ * installing/uninstalling.
+ */
+public class WearPackageArgs {
+ private static final String KEY_PACKAGE_NAME =
+ "com.google.android.clockwork.EXTRA_PACKAGE_NAME";
+ private static final String KEY_ASSET_URI =
+ "com.google.android.clockwork.EXTRA_ASSET_URI";
+ private static final String KEY_START_ID =
+ "com.google.android.clockwork.EXTRA_START_ID";
+ private static final String KEY_PERM_URI =
+ "com.google.android.clockwork.EXTRA_PERM_URI";
+ private static final String KEY_CHECK_PERMS =
+ "com.google.android.clockwork.EXTRA_CHECK_PERMS";
+ private static final String KEY_SKIP_IF_SAME_VERSION =
+ "com.google.android.clockwork.EXTRA_SKIP_IF_SAME_VERSION";
+ private static final String KEY_COMPRESSION_ALG =
+ "com.google.android.clockwork.EXTRA_KEY_COMPRESSION_ALG";
+ private static final String KEY_COMPANION_SDK_VERSION =
+ "com.google.android.clockwork.EXTRA_KEY_COMPANION_SDK_VERSION";
+ private static final String KEY_COMPANION_DEVICE_VERSION =
+ "com.google.android.clockwork.EXTRA_KEY_COMPANION_DEVICE_VERSION";
+ private static final String KEY_SHOULD_CHECK_GMS_DEPENDENCY =
+ "com.google.android.clockwork.EXTRA_KEY_SHOULD_CHECK_GMS_DEPENDENCY";
+ private static final String KEY_SKIP_IF_LOWER_VERSION =
+ "com.google.android.clockwork.EXTRA_SKIP_IF_LOWER_VERSION";
+
+ public static String getPackageName(Bundle b) {
+ return b.getString(KEY_PACKAGE_NAME);
+ }
+
+ public static Bundle setPackageName(Bundle b, String packageName) {
+ b.putString(KEY_PACKAGE_NAME, packageName);
+ return b;
+ }
+
+ public static Uri getAssetUri(Bundle b) {
+ return b.getParcelable(KEY_ASSET_URI);
+ }
+
+ public static Uri getPermUri(Bundle b) {
+ return b.getParcelable(KEY_PERM_URI);
+ }
+
+ public static boolean checkPerms(Bundle b) {
+ return b.getBoolean(KEY_CHECK_PERMS);
+ }
+
+ public static boolean skipIfSameVersion(Bundle b) {
+ return b.getBoolean(KEY_SKIP_IF_SAME_VERSION);
+ }
+
+ public static int getCompanionSdkVersion(Bundle b) {
+ return b.getInt(KEY_COMPANION_SDK_VERSION);
+ }
+
+ public static int getCompanionDeviceVersion(Bundle b) {
+ return b.getInt(KEY_COMPANION_DEVICE_VERSION);
+ }
+
+ public static String getCompressionAlg(Bundle b) {
+ return b.getString(KEY_COMPRESSION_ALG);
+ }
+
+ public static int getStartId(Bundle b) {
+ return b.getInt(KEY_START_ID);
+ }
+
+ public static boolean skipIfLowerVersion(Bundle b) {
+ return b.getBoolean(KEY_SKIP_IF_LOWER_VERSION, false);
+ }
+
+ public static Bundle setStartId(Bundle b, int startId) {
+ b.putInt(KEY_START_ID, startId);
+ return b;
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
new file mode 100644
index 0000000..02b9d29
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageIconProvider.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+import android.annotation.TargetApi;
+import android.app.ActivityManager;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.List;
+
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+public class WearPackageIconProvider extends ContentProvider {
+ private static final String TAG = "WearPackageIconProvider";
+ public static final String AUTHORITY = "com.google.android.packageinstaller.wear.provider";
+
+ private static final String REQUIRED_PERMISSION =
+ "com.google.android.permission.INSTALL_WEARABLE_PACKAGES";
+
+ /** MIME types. */
+ public static final String ICON_TYPE = "vnd.android.cursor.item/cw_package_icon";
+
+ @Override
+ public boolean onCreate() {
+ return true;
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ throw new UnsupportedOperationException("Query is not supported.");
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ if (uri == null) {
+ throw new IllegalArgumentException("URI passed in is null.");
+ }
+
+ if (AUTHORITY.equals(uri.getEncodedAuthority())) {
+ return ICON_TYPE;
+ }
+ return null;
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException("Insert is not supported.");
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ if (uri == null) {
+ throw new IllegalArgumentException("URI passed in is null.");
+ }
+
+ enforcePermissions(uri);
+
+ if (ICON_TYPE.equals(getType(uri))) {
+ final File file = WearPackageUtil.getIconFile(
+ this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
+ if (file != null) {
+ file.delete();
+ }
+ }
+
+ return 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException("Update is not supported.");
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(
+ Uri uri, @SuppressWarnings("unused") String mode) throws FileNotFoundException {
+ if (uri == null) {
+ throw new IllegalArgumentException("URI passed in is null.");
+ }
+
+ enforcePermissions(uri);
+
+ if (ICON_TYPE.equals(getType(uri))) {
+ final File file = WearPackageUtil.getIconFile(
+ this.getContext().getApplicationContext(), getPackageNameFromUri(uri));
+ if (file != null) {
+ return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+ }
+ }
+ return null;
+ }
+
+ public static Uri getUriForPackage(final String packageName) {
+ return Uri.parse("content://" + AUTHORITY + "/icons/" + packageName + ".icon");
+ }
+
+ private String getPackageNameFromUri(Uri uri) {
+ if (uri == null) {
+ return null;
+ }
+ List<String> pathSegments = uri.getPathSegments();
+ String packageName = pathSegments.get(pathSegments.size() - 1);
+
+ if (packageName.endsWith(".icon")) {
+ packageName = packageName.substring(0, packageName.lastIndexOf("."));
+ }
+ return packageName;
+ }
+
+ /**
+ * Make sure the calling app is either a system app or the same app or has the right permission.
+ * @throws SecurityException if the caller has insufficient permissions.
+ */
+ @TargetApi(Build.VERSION_CODES.BASE_1_1)
+ private void enforcePermissions(Uri uri) {
+ // Redo some of the permission check in {@link ContentProvider}. Just add an extra check to
+ // allow System process to access this provider.
+ Context context = getContext();
+ final int pid = Binder.getCallingPid();
+ final int uid = Binder.getCallingUid();
+ final int myUid = android.os.Process.myUid();
+
+ if (uid == myUid || isSystemApp(context, pid)) {
+ return;
+ }
+
+ if (context.checkPermission(REQUIRED_PERMISSION, pid, uid) == PERMISSION_GRANTED) {
+ return;
+ }
+
+ // last chance, check against any uri grants
+ if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ == PERMISSION_GRANTED) {
+ return;
+ }
+
+ throw new SecurityException("Permission Denial: reading "
+ + getClass().getName() + " uri " + uri + " from pid=" + pid
+ + ", uid=" + uid);
+ }
+
+ /**
+ * From the pid of the calling process, figure out whether this is a system app or not. We do
+ * this by checking the application information corresponding to the pid and then checking if
+ * FLAG_SYSTEM is set.
+ */
+ @TargetApi(Build.VERSION_CODES.CUPCAKE)
+ private boolean isSystemApp(Context context, int pid) {
+ // Get the Activity Manager Object
+ ActivityManager aManager =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ // Get the list of running Applications
+ List<ActivityManager.RunningAppProcessInfo> rapInfoList =
+ aManager.getRunningAppProcesses();
+ for (ActivityManager.RunningAppProcessInfo rapInfo : rapInfoList) {
+ if (rapInfo.pid == pid) {
+ try {
+ PackageInfo pkgInfo = context.getPackageManager().getPackageInfo(
+ rapInfo.pkgList[0], 0);
+ if (pkgInfo != null && pkgInfo.applicationInfo != null &&
+ (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ Log.d(TAG, pid + " is a system app.");
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "Could not find package information.", e);
+ return false;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
new file mode 100644
index 0000000..e5f7613
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
@@ -0,0 +1,589 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.FeatureInfo;
+import android.content.pm.IPackageDeleteObserver;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.PowerManager;
+import android.os.Process;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.packageinstaller.DeviceUtils;
+import com.android.packageinstaller.PackageUtil;
+import com.android.packageinstaller.R;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Service that will install/uninstall packages. It will check for permissions and features as well.
+ *
+ * -----------
+ *
+ * Debugging information:
+ *
+ * Install Action example:
+ * adb shell am startservice -a com.android.packageinstaller.wear.INSTALL_PACKAGE \
+ * -d package://com.google.android.gms \
+ * --eu com.google.android.clockwork.EXTRA_ASSET_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/wearable/com.google.android.gms/apk \
+ * --es android.intent.extra.INSTALLER_PACKAGE_NAME com.google.android.gms \
+ * --ez com.google.android.clockwork.EXTRA_CHECK_PERMS false \
+ * --eu com.google.android.clockwork.EXTRA_PERM_URI content://com.google.android.clockwork.home.provider/host/com.google.android.wearable.app/permissions \
+ * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
+ *
+ * Uninstall Action example:
+ * adb shell am startservice -a com.android.packageinstaller.wear.UNINSTALL_PACKAGE \
+ * -d package://com.google.android.gms \
+ * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
+ *
+ * Retry GMS:
+ * adb shell am startservice -a com.android.packageinstaller.wear.RETRY_GMS \
+ * com.android.packageinstaller/com.android.packageinstaller.wear.WearPackageInstallerService
+ */
+public class WearPackageInstallerService extends Service {
+ private static final String TAG = "WearPkgInstallerService";
+
+ private static final String WEAR_APPS_CHANNEL = "wear_app_install_uninstall";
+
+ private final int START_INSTALL = 1;
+ private final int START_UNINSTALL = 2;
+
+ private int mInstallNotificationId = 1;
+ private final Map<String, Integer> mNotifIdMap = new ArrayMap<>();
+
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
+ }
+
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case START_INSTALL:
+ installPackage(msg.getData());
+ break;
+ case START_UNINSTALL:
+ uninstallPackage(msg.getData());
+ break;
+ }
+ }
+ }
+ private ServiceHandler mServiceHandler;
+ private NotificationChannel mNotificationChannel;
+ private static volatile PowerManager.WakeLock lockStatic = null;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ HandlerThread thread = new HandlerThread("PackageInstallerThread",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+
+ mServiceHandler = new ServiceHandler(thread.getLooper());
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (!DeviceUtils.isWear(this)) {
+ Log.w(TAG, "Not running on wearable.");
+ finishServiceEarly(startId);
+ return START_NOT_STICKY;
+ }
+
+ if (intent == null) {
+ Log.w(TAG, "Got null intent.");
+ finishServiceEarly(startId);
+ return START_NOT_STICKY;
+ }
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Got install/uninstall request " + intent);
+ }
+
+ Uri packageUri = intent.getData();
+ if (packageUri == null) {
+ Log.e(TAG, "No package URI in intent");
+ finishServiceEarly(startId);
+ return START_NOT_STICKY;
+ }
+
+ final String packageName = WearPackageUtil.getSanitizedPackageName(packageUri);
+ if (packageName == null) {
+ Log.e(TAG, "Invalid package name in URI (expected package:<pkgName>): " + packageUri);
+ finishServiceEarly(startId);
+ return START_NOT_STICKY;
+ }
+
+ PowerManager.WakeLock lock = getLock(this.getApplicationContext());
+ if (!lock.isHeld()) {
+ lock.acquire();
+ }
+
+ Bundle intentBundle = intent.getExtras();
+ if (intentBundle == null) {
+ intentBundle = new Bundle();
+ }
+ WearPackageArgs.setStartId(intentBundle, startId);
+ WearPackageArgs.setPackageName(intentBundle, packageName);
+ Message msg;
+ String notifTitle;
+ if (Intent.ACTION_INSTALL_PACKAGE.equals(intent.getAction())) {
+ msg = mServiceHandler.obtainMessage(START_INSTALL);
+ notifTitle = getString(R.string.installing);
+ } else if (Intent.ACTION_UNINSTALL_PACKAGE.equals(intent.getAction())) {
+ msg = mServiceHandler.obtainMessage(START_UNINSTALL);
+ notifTitle = getString(R.string.uninstalling);
+ } else {
+ Log.e(TAG, "Unknown action : " + intent.getAction());
+ finishServiceEarly(startId);
+ return START_NOT_STICKY;
+ }
+ Pair<Integer, Notification> notifPair = buildNotification(packageName, notifTitle);
+ startForeground(notifPair.first, notifPair.second);
+ msg.setData(intentBundle);
+ mServiceHandler.sendMessage(msg);
+ return START_NOT_STICKY;
+ }
+
+ private void installPackage(Bundle argsBundle) {
+ int startId = WearPackageArgs.getStartId(argsBundle);
+ final String packageName = WearPackageArgs.getPackageName(argsBundle);
+ final Uri assetUri = WearPackageArgs.getAssetUri(argsBundle);
+ final Uri permUri = WearPackageArgs.getPermUri(argsBundle);
+ boolean checkPerms = WearPackageArgs.checkPerms(argsBundle);
+ boolean skipIfSameVersion = WearPackageArgs.skipIfSameVersion(argsBundle);
+ int companionSdkVersion = WearPackageArgs.getCompanionSdkVersion(argsBundle);
+ int companionDeviceVersion = WearPackageArgs.getCompanionDeviceVersion(argsBundle);
+ String compressionAlg = WearPackageArgs.getCompressionAlg(argsBundle);
+ boolean skipIfLowerVersion = WearPackageArgs.skipIfLowerVersion(argsBundle);
+
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Installing package: " + packageName + ", assetUri: " + assetUri +
+ ",permUri: " + permUri + ", startId: " + startId + ", checkPerms: " +
+ checkPerms + ", skipIfSameVersion: " + skipIfSameVersion +
+ ", compressionAlg: " + compressionAlg + ", companionSdkVersion: " +
+ companionSdkVersion + ", companionDeviceVersion: " + companionDeviceVersion +
+ ", skipIfLowerVersion: " + skipIfLowerVersion);
+ }
+ final PackageManager pm = getPackageManager();
+ File tempFile = null;
+ int installFlags = 0;
+ PowerManager.WakeLock lock = getLock(this.getApplicationContext());
+ boolean messageSent = false;
+ try {
+ PackageInfo existingPkgInfo = null;
+ try {
+ existingPkgInfo = pm.getPackageInfo(packageName,
+ PackageManager.MATCH_ANY_USER | PackageManager.GET_PERMISSIONS);
+ if (existingPkgInfo != null) {
+ installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // Ignore this exception. We could not find the package, will treat as a new
+ // installation.
+ }
+ if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Replacing package:" + packageName);
+ }
+ }
+ // TODO(28021618): This was left as a temp file due to the fact that this code is being
+ // deprecated and that we need the bare minimum to continue working moving forward
+ // If this code is used as reference, this permission logic might want to be
+ // reworked to use a stream instead of a file so that we don't need to write a
+ // file at all. Note that there might be some trickiness with opening a stream
+ // for multiple users.
+ ParcelFileDescriptor parcelFd = getContentResolver()
+ .openFileDescriptor(assetUri, "r");
+ tempFile = WearPackageUtil.getFileFromFd(WearPackageInstallerService.this,
+ parcelFd, packageName, compressionAlg);
+ if (tempFile == null) {
+ Log.e(TAG, "Could not create a temp file from FD for " + packageName);
+ return;
+ }
+ PackageParser.Package pkg = PackageUtil.getPackageInfo(this, tempFile);
+ if (pkg == null) {
+ Log.e(TAG, "Could not parse apk information for " + packageName);
+ return;
+ }
+
+ if (!pkg.packageName.equals(packageName)) {
+ Log.e(TAG, "Wearable Package Name has to match what is provided for " +
+ packageName);
+ return;
+ }
+
+ pkg.applicationInfo.sourceDir = tempFile.getPath();
+ pkg.applicationInfo.publicSourceDir = tempFile.getPath();
+ getLabelAndUpdateNotification(packageName,
+ getString(R.string.installing_app, pkg.applicationInfo.loadLabel(pm)));
+
+ List<String> wearablePerms = pkg.requestedPermissions;
+
+ // Log if the installed pkg has a higher version number.
+ if (existingPkgInfo != null) {
+ if (existingPkgInfo.getLongVersionCode() == pkg.getLongVersionCode()) {
+ if (skipIfSameVersion) {
+ Log.w(TAG, "Version number (" + pkg.getLongVersionCode() +
+ ") of new app is equal to existing app for " + packageName +
+ "; not installing due to versionCheck");
+ return;
+ } else {
+ Log.w(TAG, "Version number of new app (" + pkg.getLongVersionCode() +
+ ") is equal to existing app for " + packageName);
+ }
+ } else if (existingPkgInfo.getLongVersionCode() > pkg.getLongVersionCode()) {
+ if (skipIfLowerVersion) {
+ // Starting in Feldspar, we are not going to allow downgrades of any app.
+ Log.w(TAG, "Version number of new app (" + pkg.getLongVersionCode() +
+ ") is lower than existing app ( "
+ + existingPkgInfo.getLongVersionCode() +
+ ") for " + packageName + "; not installing due to versionCheck");
+ return;
+ } else {
+ Log.w(TAG, "Version number of new app (" + pkg.getLongVersionCode() +
+ ") is lower than existing app ( "
+ + existingPkgInfo.getLongVersionCode() + ") for " + packageName);
+ }
+ }
+
+ // Following the Android Phone model, we should only check for permissions for any
+ // newly defined perms.
+ if (existingPkgInfo.requestedPermissions != null) {
+ for (int i = 0; i < existingPkgInfo.requestedPermissions.length; ++i) {
+ // If the permission is granted, then we will not ask to request it again.
+ if ((existingPkgInfo.requestedPermissionsFlags[i] &
+ PackageInfo.REQUESTED_PERMISSION_GRANTED) != 0) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, existingPkgInfo.requestedPermissions[i] +
+ " is already granted for " + packageName);
+ }
+ wearablePerms.remove(existingPkgInfo.requestedPermissions[i]);
+ }
+ }
+ }
+ }
+
+ // Check that the wearable has all the features.
+ boolean hasAllFeatures = true;
+ if (pkg.reqFeatures != null) {
+ for (FeatureInfo feature : pkg.reqFeatures) {
+ if (feature.name != null && !pm.hasSystemFeature(feature.name) &&
+ (feature.flags & FeatureInfo.FLAG_REQUIRED) != 0) {
+ Log.e(TAG, "Wearable does not have required feature: " + feature +
+ " for " + packageName);
+ hasAllFeatures = false;
+ }
+ }
+ }
+
+ if (!hasAllFeatures) {
+ return;
+ }
+
+ // Check permissions on both the new wearable package and also on the already installed
+ // wearable package.
+ // If the app is targeting API level 23, we will also start a service in ClockworkHome
+ // which will ultimately prompt the user to accept/reject permissions.
+ if (checkPerms && !checkPermissions(pkg, companionSdkVersion, companionDeviceVersion,
+ permUri, wearablePerms, tempFile)) {
+ Log.w(TAG, "Wearable does not have enough permissions.");
+ return;
+ }
+
+ // Finally install the package.
+ ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(assetUri, "r");
+ PackageInstallerFactory.getPackageInstaller(this).install(packageName, fd,
+ new PackageInstallListener(this, lock, startId, packageName));
+
+ messageSent = true;
+ Log.i(TAG, "Sent installation request for " + packageName);
+ } catch (FileNotFoundException e) {
+ Log.e(TAG, "Could not find the file with URI " + assetUri, e);
+ } finally {
+ if (!messageSent) {
+ // Some error happened. If the message has been sent, we can wait for the observer
+ // which will finish the service.
+ if (tempFile != null) {
+ tempFile.delete();
+ }
+ finishService(lock, startId);
+ }
+ }
+ }
+
+ // TODO: This was left using the old PackageManager API due to the fact that this code is being
+ // deprecated and that we need the bare minimum to continue working moving forward
+ // If this code is used as reference, this logic should be reworked to use the new
+ // PackageInstaller APIs similar to how installPackage was reworked
+ private void uninstallPackage(Bundle argsBundle) {
+ int startId = WearPackageArgs.getStartId(argsBundle);
+ final String packageName = WearPackageArgs.getPackageName(argsBundle);
+
+ PowerManager.WakeLock lock = getLock(this.getApplicationContext());
+ final PackageManager pm = getPackageManager();
+ try {
+ PackageInfo pkgInfo = pm.getPackageInfo(packageName, 0);
+ getLabelAndUpdateNotification(packageName,
+ getString(R.string.uninstalling_app, pkgInfo.applicationInfo.loadLabel(pm)));
+
+ // Found package, send uninstall request.
+ pm.deletePackage(packageName, new PackageDeleteObserver(lock, startId),
+ PackageManager.DELETE_ALL_USERS);
+
+ Log.i(TAG, "Sent delete request for " + packageName);
+ } catch (IllegalArgumentException | PackageManager.NameNotFoundException e) {
+ // Couldn't find the package, no need to call uninstall.
+ Log.w(TAG, "Could not find package, not deleting " + packageName, e);
+ finishService(lock, startId);
+ }
+ }
+
+ private boolean checkPermissions(PackageParser.Package pkg, int companionSdkVersion,
+ int companionDeviceVersion, Uri permUri, List<String> wearablePermissions,
+ File apkFile) {
+ // Assumption: We are running on Android O.
+ // If the Phone App is targeting M, all permissions may not have been granted to the phone
+ // app. If the Wear App is then not targeting M, there may be permissions that are not
+ // granted on the Phone app (by the user) right now and we cannot just grant it for the Wear
+ // app.
+ if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
+ // Install the app if Wear App is ready for the new perms model.
+ return true;
+ }
+
+ if (!doesWearHaveUngrantedPerms(pkg.packageName, permUri, wearablePermissions)) {
+ // All permissions requested by the watch are already granted on the phone, no need
+ // to do anything.
+ return true;
+ }
+
+ // Log an error if Wear is targeting < 23 and phone is targeting >= 23.
+ if (companionSdkVersion == 0 || companionSdkVersion >= Build.VERSION_CODES.M) {
+ Log.e(TAG, "MNC: Wear app's targetSdkVersion should be at least 23, if "
+ + "phone app is targeting at least 23, will continue.");
+ }
+
+ return false;
+ }
+
+ /**
+ * Given a {@string packageName} corresponding to a phone app, query the provider for all the
+ * perms that are granted.
+ *
+ * @return true if the Wear App has any perms that have not been granted yet on the phone side.
+ * @return true if there is any error cases.
+ */
+ private boolean doesWearHaveUngrantedPerms(String packageName, Uri permUri,
+ List<String> wearablePermissions) {
+ if (permUri == null) {
+ Log.e(TAG, "Permission URI is null");
+ // Pretend there is an ungranted permission to avoid installing for error cases.
+ return true;
+ }
+ Cursor permCursor = getContentResolver().query(permUri, null, null, null, null);
+ if (permCursor == null) {
+ Log.e(TAG, "Could not get the cursor for the permissions");
+ // Pretend there is an ungranted permission to avoid installing for error cases.
+ return true;
+ }
+
+ Set<String> grantedPerms = new HashSet<>();
+ Set<String> ungrantedPerms = new HashSet<>();
+ while(permCursor.moveToNext()) {
+ // Make sure that the MatrixCursor returned by the ContentProvider has 2 columns and
+ // verify their types.
+ if (permCursor.getColumnCount() == 2
+ && Cursor.FIELD_TYPE_STRING == permCursor.getType(0)
+ && Cursor.FIELD_TYPE_INTEGER == permCursor.getType(1)) {
+ String perm = permCursor.getString(0);
+ Integer granted = permCursor.getInt(1);
+ if (granted == 1) {
+ grantedPerms.add(perm);
+ } else {
+ ungrantedPerms.add(perm);
+ }
+ }
+ }
+ permCursor.close();
+
+ boolean hasUngrantedPerm = false;
+ for (String wearablePerm : wearablePermissions) {
+ if (!grantedPerms.contains(wearablePerm)) {
+ hasUngrantedPerm = true;
+ if (!ungrantedPerms.contains(wearablePerm)) {
+ // This is an error condition. This means that the wearable has permissions that
+ // are not even declared in its host app. This is a developer error.
+ Log.e(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm
+ + "\" that is not defined in the host application's manifest.");
+ } else {
+ Log.w(TAG, "Wearable " + packageName + " has a permission \"" + wearablePerm +
+ "\" that is not granted in the host application.");
+ }
+ }
+ }
+ return hasUngrantedPerm;
+ }
+
+ /** Finishes the service after fulfilling obligation to call startForeground. */
+ private void finishServiceEarly(int startId) {
+ Pair<Integer, Notification> notifPair = buildNotification(
+ getApplicationContext().getPackageName(), "");
+ startForeground(notifPair.first, notifPair.second);
+ finishService(null, startId);
+ }
+
+ private void finishService(PowerManager.WakeLock lock, int startId) {
+ if (lock != null && lock.isHeld()) {
+ lock.release();
+ }
+ stopSelf(startId);
+ }
+
+ private synchronized PowerManager.WakeLock getLock(Context context) {
+ if (lockStatic == null) {
+ PowerManager mgr =
+ (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ lockStatic = mgr.newWakeLock(
+ PowerManager.PARTIAL_WAKE_LOCK, context.getClass().getSimpleName());
+ lockStatic.setReferenceCounted(true);
+ }
+ return lockStatic;
+ }
+
+ private class PackageInstallListener implements PackageInstallerImpl.InstallListener {
+ private Context mContext;
+ private PowerManager.WakeLock mWakeLock;
+ private int mStartId;
+ private String mApplicationPackageName;
+ private PackageInstallListener(Context context, PowerManager.WakeLock wakeLock,
+ int startId, String applicationPackageName) {
+ mContext = context;
+ mWakeLock = wakeLock;
+ mStartId = startId;
+ mApplicationPackageName = applicationPackageName;
+ }
+
+ @Override
+ public void installBeginning() {
+ Log.i(TAG, "Package " + mApplicationPackageName + " is being installed.");
+ }
+
+ @Override
+ public void installSucceeded() {
+ try {
+ Log.i(TAG, "Package " + mApplicationPackageName + " was installed.");
+
+ // Delete tempFile from the file system.
+ File tempFile = WearPackageUtil.getTemporaryFile(mContext, mApplicationPackageName);
+ if (tempFile != null) {
+ tempFile.delete();
+ }
+ } finally {
+ finishService(mWakeLock, mStartId);
+ }
+ }
+
+ @Override
+ public void installFailed(int errorCode, String errorDesc) {
+ Log.e(TAG, "Package install failed " + mApplicationPackageName
+ + ", errorCode " + errorCode);
+ finishService(mWakeLock, mStartId);
+ }
+ }
+
+ private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
+ private PowerManager.WakeLock mWakeLock;
+ private int mStartId;
+
+ private PackageDeleteObserver(PowerManager.WakeLock wakeLock, int startId) {
+ mWakeLock = wakeLock;
+ mStartId = startId;
+ }
+
+ public void packageDeleted(String packageName, int returnCode) {
+ try {
+ if (returnCode >= 0) {
+ Log.i(TAG, "Package " + packageName + " was uninstalled.");
+ } else {
+ Log.e(TAG, "Package uninstall failed " + packageName + ", returnCode " +
+ returnCode);
+ }
+ } finally {
+ finishService(mWakeLock, mStartId);
+ }
+ }
+ }
+
+ private synchronized Pair<Integer, Notification> buildNotification(final String packageName,
+ final String title) {
+ int notifId;
+ if (mNotifIdMap.containsKey(packageName)) {
+ notifId = mNotifIdMap.get(packageName);
+ } else {
+ notifId = mInstallNotificationId++;
+ mNotifIdMap.put(packageName, notifId);
+ }
+
+ if (mNotificationChannel == null) {
+ mNotificationChannel = new NotificationChannel(WEAR_APPS_CHANNEL,
+ getString(R.string.wear_app_channel), NotificationManager.IMPORTANCE_MIN);
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(mNotificationChannel);
+ }
+ return new Pair<>(notifId, new Notification.Builder(this, WEAR_APPS_CHANNEL)
+ .setSmallIcon(R.drawable.ic_file_download)
+ .setContentTitle(title)
+ .build());
+ }
+
+ private void getLabelAndUpdateNotification(String packageName, String title) {
+ // Update notification since we have a label now.
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ Pair<Integer, Notification> notifPair = buildNotification(packageName, title);
+ notificationManager.notify(notifPair.first, notifPair.second);
+ }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
new file mode 100644
index 0000000..bc740ab
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageUtil.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.packageinstaller.wear;
+
+import android.content.Context;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.text.TextUtils;
+import android.util.Log;
+
+import org.tukaani.xz.LZMAInputStream;
+import org.tukaani.xz.XZInputStream;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class WearPackageUtil {
+ private static final String TAG = "WearablePkgInstaller";
+
+ private static final String COMPRESSION_LZMA = "lzma";
+ private static final String COMPRESSION_XZ = "xz";
+
+ public static File getTemporaryFile(Context context, String packageName) {
+ try {
+ File newFileDir = new File(context.getFilesDir(), "tmp");
+ newFileDir.mkdirs();
+ Os.chmod(newFileDir.getAbsolutePath(), 0771);
+ File newFile = new File(newFileDir, packageName + ".apk");
+ return newFile;
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to open.", e);
+ return null;
+ }
+ }
+
+ public static File getIconFile(final Context context, final String packageName) {
+ try {
+ File newFileDir = new File(context.getFilesDir(), "images/icons");
+ newFileDir.mkdirs();
+ Os.chmod(newFileDir.getAbsolutePath(), 0771);
+ return new File(newFileDir, packageName + ".icon");
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Failed to open.", e);
+ return null;
+ }
+ }
+
+ /**
+ * In order to make sure that the Wearable Asset Manager has a reasonable apk that can be used
+ * by the PackageManager, we will parse it before sending it to the PackageManager.
+ * Unfortunately, PackageParser needs a file to parse. So, we have to temporarily convert the fd
+ * to a File.
+ *
+ * @param context
+ * @param fd FileDescriptor to convert to File
+ * @param packageName Name of package, will define the name of the file
+ * @param compressionAlg Can be null. For ALT mode the APK will be compressed. We will
+ * decompress it here
+ */
+ public static File getFileFromFd(Context context, ParcelFileDescriptor fd,
+ String packageName, String compressionAlg) {
+ File newFile = getTemporaryFile(context, packageName);
+ if (fd == null || fd.getFileDescriptor() == null) {
+ return null;
+ }
+ InputStream fr = new ParcelFileDescriptor.AutoCloseInputStream(fd);
+ try {
+ if (TextUtils.equals(compressionAlg, COMPRESSION_XZ)) {
+ fr = new XZInputStream(fr);
+ } else if (TextUtils.equals(compressionAlg, COMPRESSION_LZMA)) {
+ fr = new LZMAInputStream(fr);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Compression was set to " + compressionAlg + ", but could not decode ", e);
+ return null;
+ }
+
+ int nRead;
+ byte[] data = new byte[1024];
+ try {
+ final FileOutputStream fo = new FileOutputStream(newFile);
+ while ((nRead = fr.read(data, 0, data.length)) != -1) {
+ fo.write(data, 0, nRead);
+ }
+ fo.flush();
+ fo.close();
+ Os.chmod(newFile.getAbsolutePath(), 0644);
+ return newFile;
+ } catch (IOException e) {
+ Log.e(TAG, "Reading from Asset FD or writing to temp file failed ", e);
+ return null;
+ } catch (ErrnoException e) {
+ Log.e(TAG, "Could not set permissions on file ", e);
+ return null;
+ } finally {
+ try {
+ fr.close();
+ } catch (IOException e) {
+ Log.e(TAG, "Failed to close the file from FD ", e);
+ }
+ }
+ }
+
+ /**
+ * @return com.google.com from expected formats like
+ * Uri: package:com.google.com, package:/com.google.com, package://com.google.com
+ */
+ public static String getSanitizedPackageName(Uri packageUri) {
+ String packageName = packageUri.getEncodedSchemeSpecificPart();
+ if (packageName != null) {
+ return packageName.replaceAll("^/+", "");
+ }
+ return packageName;
+ }
+}
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 50d9c17..d30be58 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -189,9 +189,9 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"La configuració de la VPN no està disponible per a aquest usuari."</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"La configuració de compartició de xarxa no està disponible per a aquest usuari."</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"La configuració del nom del punt d\'accés no està disponible per a aquest usuari."</string>
- <string name="enable_adb" msgid="7982306934419797485">"Depuració USB"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"Depuració per USB"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"Activa el mode de depuració quan el dispositiu estigui connectat per USB"</string>
- <string name="clear_adb_keys" msgid="4038889221503122743">"Revoca autoritzacions de depuració USB"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Revoca autoritzacions de depuració per USB"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Drecera per a informe d\'errors"</string>
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Mostra un botó al menú d\'engegada per crear un informe d\'errors"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Pantalla sempre activa"</string>
@@ -251,9 +251,9 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Inspecció d\'atributs de visualització"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mantén les dades mòbils sempre actives, fins i tot quan la Wi‑Fi està activada (per canviar de xarxa ràpidament)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Fes servir l\'acceleració per maquinari per compartir la xarxa, si està disponible"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració USB?"</string>
- <string name="adb_warning_message" msgid="7316799925425402244">"La depuració USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
- <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració d\'USB dels ordinadors que has autoritzat anteriorment?"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Voleu permetre la depuració per USB?"</string>
+ <string name="adb_warning_message" msgid="7316799925425402244">"La depuració per USB només està indicada per a activitats de desenvolupament. Fes-la servir intercanviar dades entre l\'ordinador i el dispositiu, per instal·lar aplicacions al dispositiu sense rebre notificacions i per llegir dades de registre."</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Vols revocar l\'accés a la depuració per USB dels ordinadors que has autoritzat anteriorment?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Vols permetre la conf. de desenvolupament?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"Aquesta configuració només està prevista per a usos de desenvolupament. Pot fer que el dispositiu i que les aplicacions s\'interrompin o tinguin un comportament inadequat."</string>
<string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Verifica aplicacions per USB"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 1579d8f..a90231a 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -189,9 +189,9 @@
<string name="vpn_settings_not_available" msgid="956841430176985598">"Nastavení sítě VPN pro tohoto uživatele není dostupné."</string>
<string name="tethering_settings_not_available" msgid="6765770438438291012">"Nastavení sdíleného připojení pro tohoto uživatele není dostupné."</string>
<string name="apn_settings_not_available" msgid="7873729032165324000">"Nastavení přístupového bodu pro tohoto uživatele není dostupné."</string>
- <string name="enable_adb" msgid="7982306934419797485">"Ladění USB"</string>
+ <string name="enable_adb" msgid="7982306934419797485">"Ladění přes USB"</string>
<string name="enable_adb_summary" msgid="4881186971746056635">"Povolit režim ladění s připojeným zařízením USB"</string>
- <string name="clear_adb_keys" msgid="4038889221503122743">"Zrušit autorizace k ladění USB"</string>
+ <string name="clear_adb_keys" msgid="4038889221503122743">"Zrušit autorizace k ladění přes USB"</string>
<string name="bugreport_in_power" msgid="7923901846375587241">"Zástupce hlášení chyb"</string>
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Zobrazit v hlavní nabídce tlačítko k vygenerování chybového hlášení"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Nevypínat obrazovku"</string>
@@ -251,9 +251,9 @@
<string name="debug_view_attributes" msgid="6485448367803310384">"Kontrola atributu zobrazení"</string>
<string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Mobilní data budou vždy ponechána aktivní, i když bude aktivní Wi-Fi (za účelem rychlého přepínání sítí)."</string>
<string name="tethering_hardware_offload_summary" msgid="7726082075333346982">"Pokud je k dispozici hardwarová akceleraci tetheringu, použít ji"</string>
- <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění USB?"</string>
+ <string name="adb_warning_title" msgid="6234463310896563253">"Povolit ladění přes USB?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"Ladění prostřednictvím rozhraní USB je určeno pouze pro účely vývoje. Použijte je ke kopírování dat mezi počítačem a zařízením, instalaci aplikací do zařízení bez upozornění a čtení dat protokolů."</string>
- <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
+ <string name="adb_keys_warning_message" msgid="5659849457135841625">"Zrušit přístup k ladění přes USB ze všech počítačů, které jste v minulosti autorizovali?"</string>
<string name="dev_settings_warning_title" msgid="7244607768088540165">"Povolit nastavení pro vývojáře?"</string>
<string name="dev_settings_warning_message" msgid="2298337781139097964">"Tato nastavení jsou určena pouze pro vývojáře. Mohou způsobit rozbití nebo nesprávné fungování zařízení a nainstalovaných aplikací."</string>
<string name="verify_apps_over_usb_title" msgid="4177086489869041953">"Ověřit aplikace z USB"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index ec7bf98..0410977 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -165,7 +165,7 @@
<string name="tts_engine_settings_title" msgid="3499112142425680334">"<xliff:g id="TTS_ENGINE_NAME">%s</xliff:g> motorraren ezarpenak"</string>
<string name="tts_engine_settings_button" msgid="1030512042040722285">"Abiarazi motorraren ezarpenak"</string>
<string name="tts_engine_preference_section_title" msgid="448294500990971413">"Motor hobetsia"</string>
- <string name="tts_general_section_title" msgid="4402572014604490502">"Orokorra"</string>
+ <string name="tts_general_section_title" msgid="4402572014604490502">"Orokorrak"</string>
<string name="tts_reset_speech_pitch_title" msgid="5789394019544785915">"Berrezarri ahots-tonua"</string>
<string name="tts_reset_speech_pitch_summary" msgid="8700539616245004418">"Berrezarri testua esateko ahots-tonu lehenetsia."</string>
<string-array name="tts_rate_entries">
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 5eac8fa..e94dd73 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -371,10 +371,10 @@
<string name="power_remaining_duration_only_enhanced" msgid="4189311599812296592">"Temps restant en fonction de votre utilisation : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_discharging_duration_enhanced" msgid="1992003260664804080">"Temps restant en fonction de votre utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>) : environ <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
<string name="power_remaining_duration_only_short" msgid="3463575350656389957">"Temps restant : <xliff:g id="TIME_REMAINING">%1$s</xliff:g>"</string>
- <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de l\'utilisation (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> en fonction de l\'utilisation"</string>
- <string name="power_discharge_by" msgid="6453537733650125582">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
- <string name="power_discharge_by_only" msgid="107616694963545745">"Devrait durer jusqu\'à environ <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by_enhanced" msgid="2095821536747992464">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only_enhanced" msgid="2175151772952365149">"Temps restant estimé en fonction de votre utilisation : <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="power_discharge_by" msgid="6453537733650125582">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
+ <string name="power_discharge_by_only" msgid="107616694963545745">"Temps restant estimé : <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration_only" msgid="5996752448813295329">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g>"</string>
<string name="power_remaining_less_than_duration" msgid="5751885147712659423">"Il reste moins de <xliff:g id="THRESHOLD">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
<string name="power_remaining_more_than_subtext" msgid="3176771815132876675">"Il reste plus de <xliff:g id="TIME_REMAINING">%1$s</xliff:g> (<xliff:g id="LEVEL">%2$s</xliff:g>)"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java b/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
index 6da486a..fd9d02b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/ZenDurationDialog.java
@@ -24,7 +24,6 @@
import android.provider.Settings;
import android.service.notification.Condition;
import android.service.notification.ZenModeConfig;
-import androidx.annotation.VisibleForTesting;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CompoundButton;
@@ -42,6 +41,8 @@
import java.util.Arrays;
+import androidx.annotation.VisibleForTesting;
+
public class ZenDurationDialog {
private static final int[] MINUTE_BUCKETS = ZenModeConfig.MINUTE_BUCKETS;
@VisibleForTesting protected static final int MIN_BUCKET_MINUTES = MINUTE_BUCKETS[0];
@@ -66,9 +67,9 @@
}
public Dialog createDialog() {
- int zenDuration = Settings.Global.getInt(
- mContext.getContentResolver(), Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_FOREVER);
+ int zenDuration = Settings.Secure.getInt(
+ mContext.getContentResolver(), Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_FOREVER);
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext)
.setTitle(R.string.zen_mode_duration_settings_title)
@@ -91,12 +92,12 @@
protected void updateZenDuration(int currZenDuration) {
final int checkedRadioButtonId = mZenRadioGroup.getCheckedRadioButtonId();
- int newZenDuration = Settings.Global.getInt(
- mContext.getContentResolver(), Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_FOREVER);
+ int newZenDuration = Settings.Secure.getInt(
+ mContext.getContentResolver(), Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_FOREVER);
switch (checkedRadioButtonId) {
case FOREVER_CONDITION_INDEX:
- newZenDuration = Settings.Global.ZEN_DURATION_FOREVER;
+ newZenDuration = Settings.Secure.ZEN_DURATION_FOREVER;
MetricsLogger.action(mContext,
MetricsProto.MetricsEvent.
NOTIFICATION_ZEN_MODE_DURATION_FOREVER);
@@ -110,7 +111,7 @@
newZenDuration);
break;
case ALWAYS_ASK_CONDITION_INDEX:
- newZenDuration = Settings.Global.ZEN_DURATION_PROMPT;
+ newZenDuration = Settings.Secure.ZEN_DURATION_PROMPT;
MetricsLogger.action(mContext,
MetricsProto.MetricsEvent.
NOTIFICATION_ZEN_MODE_DURATION_PROMPT);
@@ -118,8 +119,8 @@
}
if (currZenDuration != newZenDuration) {
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.ZEN_DURATION, newZenDuration);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ZEN_DURATION, newZenDuration);
}
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
index 9b491c2..c8619d8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/ZenDurationDialogTest.java
@@ -72,7 +72,7 @@
@Test
public void testAlwaysPrompt() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
Settings.Global.ZEN_DURATION_PROMPT);
mController.createDialog();
@@ -86,8 +86,8 @@
@Test
public void testForever() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_FOREVER);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_FOREVER);
mController.createDialog();
assertTrue(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
@@ -100,7 +100,7 @@
@Test
public void testSpecificDuration() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION, 45);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION, 45);
mController.createDialog();
assertFalse(mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb
@@ -114,51 +114,51 @@
@Test
public void testChooseAlwaysPromptSetting() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_FOREVER);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_FOREVER);
AlertDialog dialog = (AlertDialog) mController.createDialog();
mController.getConditionTagAt(ZenDurationDialog.ALWAYS_ASK_CONDITION_INDEX).rb.setChecked(
true);
- mController.updateZenDuration(Settings.Global.ZEN_DURATION_FOREVER);
+ mController.updateZenDuration(Settings.Secure.ZEN_DURATION_FOREVER);
- assertEquals(Settings.Global.ZEN_DURATION_PROMPT, Settings.Global.getInt(mContentResolver,
- Settings.Global.ZEN_DURATION, Settings.Global.ZEN_DURATION_FOREVER));
+ assertEquals(Settings.Secure.ZEN_DURATION_PROMPT, Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_FOREVER));
}
@Test
public void testChooseForeverSetting() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_PROMPT);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_PROMPT);
AlertDialog dialog = (AlertDialog) mController.createDialog();
mController.getConditionTagAt(ZenDurationDialog.FOREVER_CONDITION_INDEX).rb.setChecked(
true);
- mController.updateZenDuration(Settings.Global.ZEN_DURATION_PROMPT);
+ mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT);
- assertEquals(Settings.Global.ZEN_DURATION_FOREVER, Settings.Global.getInt(mContentResolver,
- Settings.Global.ZEN_DURATION, Settings.Global.ZEN_DURATION_PROMPT));
+ assertEquals(Settings.Secure.ZEN_DURATION_FOREVER, Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_PROMPT));
}
@Test
public void testChooseTimeSetting() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_PROMPT);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_PROMPT);
AlertDialog dialog = (AlertDialog) mController.createDialog();
mController.getConditionTagAt(ZenDurationDialog.COUNTDOWN_CONDITION_INDEX).rb.setChecked(
true);
- mController.updateZenDuration(Settings.Global.ZEN_DURATION_PROMPT);
+ mController.updateZenDuration(Settings.Secure.ZEN_DURATION_PROMPT);
// countdown defaults to 60 minutes:
- assertEquals(60, Settings.Global.getInt(mContentResolver,
- Settings.Global.ZEN_DURATION, Settings.Global.ZEN_DURATION_PROMPT));
+ assertEquals(60, Settings.Secure.getInt(mContentResolver,
+ Settings.Secure.ZEN_DURATION, Settings.Secure.ZEN_DURATION_PROMPT));
}
@Test
public void testGetTimeFromBucket() {
- Settings.Global.putInt(mContentResolver, Settings.Global.ZEN_DURATION,
- Settings.Global.ZEN_DURATION_PROMPT);
+ Settings.Secure.putInt(mContentResolver, Settings.Secure.ZEN_DURATION,
+ Settings.Secure.ZEN_DURATION_PROMPT);
AlertDialog dialog = (AlertDialog) mController.createDialog();
// click time button starts at 60 minutes
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index e1a602b..c53417b 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -217,4 +217,10 @@
<!-- Default for Settings.System.VIBRATE_WHEN_RINGING -->
<bool name="def_vibrate_when_ringing">false</bool>
+
+ <!-- Default for Settings.Secure.CHARGING_VIBRATION_ENABLED -->
+ <bool name="def_charging_vibration_enabled">true</bool>
+
+ <!-- Default for Settings.Secure.CHARGING_SOUNDS_ENABLED -->
+ <bool name="def_charging_sounds_enabled">true</bool>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 10c1211..007e140 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1182,9 +1182,6 @@
dumpSetting(s, p,
Settings.Global.CHARGING_STARTED_SOUND,
GlobalSettingsProto.Sounds.CHARGING_STARTED);
- dumpSetting(s, p,
- Settings.Global.CHARGING_SOUNDS_ENABLED,
- GlobalSettingsProto.Sounds.CHARGING_SOUNDS_ENABLED);
p.end(soundsToken);
final long soundTriggerToken = p.start(GlobalSettingsProto.SOUND_TRIGGER);
@@ -1478,12 +1475,6 @@
dumpSetting(s, p,
Settings.Global.ZEN_MODE_CONFIG_ETAG,
GlobalSettingsProto.Zen.MODE_CONFIG_ETAG);
- dumpSetting(s, p,
- Settings.Global.ZEN_DURATION,
- GlobalSettingsProto.Zen.DURATION);
- dumpSetting(s, p,
- Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION,
- GlobalSettingsProto.Zen.SHOW_ZEN_UPGRADE_NOTIFICATION);
p.end(zenToken);
dumpSetting(s, p,
@@ -1984,6 +1975,9 @@
dumpSetting(s, p,
Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING,
SecureSettingsProto.Notification.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING);
+ dumpSetting(s, p,
+ Settings.Secure.IN_CALL_NOTIFICATION_ENABLED,
+ SecureSettingsProto.Notification.IN_CALL_NOTIFICATION_ENABLED);
p.end(notificationToken);
final long packageVerifierToken = p.start(SecureSettingsProto.PACKAGE_VERIFIER);
@@ -2146,6 +2140,16 @@
dumpSetting(s, p,
Settings.Secure.SMS_DEFAULT_APPLICATION,
SecureSettingsProto.SMS_DEFAULT_APPLICATION);
+
+ final long soundsToken = p.start(SecureSettingsProto.SOUNDS);
+ dumpSetting(s, p,
+ Settings.Secure.CHARGING_SOUNDS_ENABLED,
+ SecureSettingsProto.Sounds.CHARGING_SOUNDS_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.CHARGING_VIBRATION_ENABLED,
+ SecureSettingsProto.Sounds.CHARGING_VIBRATION_ENABLED);
+ p.end(soundsToken);
+
dumpSetting(s, p,
Settings.Secure.SYNC_PARENT_SOUNDS,
SecureSettingsProto.SYNC_PARENT_SOUNDS);
@@ -2252,6 +2256,24 @@
SecureSettingsProto.Launcher.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
p.end(launcherToken);
+ final long zenToken = p.start(SecureSettingsProto.ZEN);
+ dumpSetting(s, p,
+ Settings.Secure.ZEN_DURATION,
+ SecureSettingsProto.Zen.DURATION);
+ dumpSetting(s, p,
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION,
+ SecureSettingsProto.Zen.SHOW_ZEN_UPGRADE_NOTIFICATION);
+ dumpSetting(s, p,
+ Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION,
+ SecureSettingsProto.Zen.SHOW_ZEN_SETTINGS_SUGGESTION);
+ dumpSetting(s, p,
+ Settings.Secure.ZEN_SETTINGS_UPDATED,
+ SecureSettingsProto.Zen.SETTINGS_UPDATED);
+ dumpSetting(s, p,
+ Settings.Secure.ZEN_SETTINGS_SUGGESTION_VIEWED,
+ SecureSettingsProto.Zen.SETTINGS_SUGGESTION_VIEWED);
+ p.end(zenToken);
+
// Please insert new settings using the same order as in SecureSettingsProto.
p.end(token);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 9592b63..1c13395 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -816,7 +816,7 @@
@Override
public void onPackageRemoved(String packageName, int uid) {
synchronized (mLock) {
- mSettingsRegistry.onPackageRemovedLocked(packageName,
+ mSettingsRegistry.removeSettingsForPackageLocked(packageName,
UserHandle.getUserId(uid));
}
}
@@ -827,6 +827,14 @@
mSettingsRegistry.onUidRemovedLocked(uid);
}
}
+
+ @Override
+ public void onPackageDataCleared(String packageName, int uid) {
+ synchronized (mLock) {
+ mSettingsRegistry.removeSettingsForPackageLocked(packageName,
+ UserHandle.getUserId(uid));
+ }
+ }
};
// package changes
@@ -2547,7 +2555,7 @@
}
}
- public void onPackageRemovedLocked(String packageName, int userId) {
+ public void removeSettingsForPackageLocked(String packageName, int userId) {
// Global and secure settings are signature protected. Apps signed
// by the platform certificate are generally not uninstalled and
// the main exception is tests. We trust components signed
@@ -2556,7 +2564,7 @@
final int systemKey = makeKey(SETTINGS_TYPE_SYSTEM, userId);
SettingsState systemSettings = mSettingsStates.get(systemKey);
if (systemSettings != null) {
- systemSettings.onPackageRemovedLocked(packageName);
+ systemSettings.removeSettingsForPackageLocked(packageName);
}
}
@@ -2935,7 +2943,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 170;
+ private static final int SETTINGS_VERSION = 171;
private final int mUserId;
@@ -3595,7 +3603,8 @@
}
if (currentVersion == 156) {
- // Version 157: Set a default value for zen duration
+ // Version 157: Set a default value for zen duration,
+ // in version 169, zen duration is moved to secure settings
final SettingsState globalSettings = getGlobalSettingsLocked();
final Setting currentSetting = globalSettings.getSettingLocked(
Global.ZEN_DURATION);
@@ -3731,32 +3740,8 @@
}
if (currentVersion == 165) {
- // Version 165: Show zen settings suggestion and zen updated
- final SettingsState settings = getGlobalSettingsLocked();
- final Setting currentSetting = settings.getSettingLocked(
- Global.SHOW_ZEN_SETTINGS_SUGGESTION);
- if (currentSetting.isNull()) {
- settings.insertSettingLocked(
- Global.SHOW_ZEN_SETTINGS_SUGGESTION, "1",
- null, true, SettingsState.SYSTEM_PACKAGE_NAME);
- }
-
- final Setting currentUpdatedSetting = settings.getSettingLocked(
- Global.ZEN_SETTINGS_UPDATED);
- if (currentUpdatedSetting.isNull()) {
- settings.insertSettingLocked(
- Global.ZEN_SETTINGS_UPDATED, "0",
- null, true, SettingsState.SYSTEM_PACKAGE_NAME);
- }
-
- final Setting currentSettingSuggestionViewed = settings.getSettingLocked(
- Global.ZEN_SETTINGS_SUGGESTION_VIEWED);
- if (currentSettingSuggestionViewed.isNull()) {
- settings.insertSettingLocked(
- Global.ZEN_SETTINGS_SUGGESTION_VIEWED, "0",
- null, true, SettingsState.SYSTEM_PACKAGE_NAME);
- }
-
+ // Version 165: MOVED: Show zen settings suggestion and zen updated settings
+ // moved to secure settings and are set in version 169
currentVersion = 166;
}
@@ -3783,15 +3768,8 @@
}
if (currentVersion == 167) {
- // Version 167: by default, vibrate for wireless charging
- final SettingsState globalSettings = getGlobalSettingsLocked();
- final Setting currentSetting = globalSettings.getSettingLocked(
- Global.CHARGING_VIBRATION_ENABLED);
- if (currentSetting.isNull()) {
- globalSettings.insertSettingLocked(
- Global.CHARGING_VIBRATION_ENABLED, "1",
- null, true, SettingsState.SYSTEM_PACKAGE_NAME);
- }
+ // Version 167: MOVED - Settings.Global.CHARGING_VIBRATION_ENABLED moved to
+ // Settings.Secure.CHARGING_VIBRATION_ENABLED, set in version 170
currentVersion = 168;
}
@@ -3811,36 +3789,112 @@
}
if (currentVersion == 169) {
- // Version 169: by default, add STREAM_VOICE_CALL to list of streams that can
- // be muted.
- final SettingsState systemSettings = getSystemSettingsLocked(userId);
- final Setting currentSetting = systemSettings.getSettingLocked(
- Settings.System.MUTE_STREAMS_AFFECTED);
- if (!currentSetting.isNull()) {
- try {
- int currentSettingIntegerValue = Integer.parseInt(
- currentSetting.getValue());
- if ((currentSettingIntegerValue
- & (1 << AudioManager.STREAM_VOICE_CALL)) == 0) {
- systemSettings.insertSettingLocked(
- Settings.System.MUTE_STREAMS_AFFECTED,
- Integer.toString(
- currentSettingIntegerValue
- | (1 << AudioManager.STREAM_VOICE_CALL)),
- null, true, SettingsState.SYSTEM_PACKAGE_NAME);
- }
- } catch (NumberFormatException e) {
- // remove the setting in case it is not a valid integer
- Slog.w("Failed to parse integer value of MUTE_STREAMS_AFFECTED"
- + "setting, removing setting", e);
- systemSettings.deleteSettingLocked(
- Settings.System.MUTE_STREAMS_AFFECTED);
- }
+ // Version 169: Set the default value for Secure Settings ZEN_DURATION,
+ // SHOW_ZEN_SETTINGS_SUGGESTION, ZEN_SETTINGS_UPDATE and
+ // ZEN_SETTINGS_SUGGESTION_VIEWED
+ final SettingsState globalSettings = getGlobalSettingsLocked();
+ final Setting globalZenDuration = globalSettings.getSettingLocked(
+ Global.ZEN_DURATION);
+
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+ final Setting secureZenDuration = secureSettings.getSettingLocked(
+ Secure.ZEN_DURATION);
+
+ // ZEN_DURATION
+ if (!globalZenDuration.isNull()) {
+ secureSettings.insertSettingLocked(
+ Secure.ZEN_DURATION, globalZenDuration.getValue(), null, false,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+
+ // set global zen duration setting to null since it's deprecated
+ globalSettings.insertSettingLocked(
+ Global.ZEN_DURATION, null, null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ } else if (secureZenDuration.isNull()) {
+ String defaultZenDuration = Integer.toString(getContext()
+ .getResources().getInteger(R.integer.def_zen_duration));
+ secureSettings.insertSettingLocked(
+ Secure.ZEN_DURATION, defaultZenDuration, null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
}
+
+ // SHOW_ZEN_SETTINGS_SUGGESTION
+ final Setting currentShowZenSettingSuggestion = secureSettings.getSettingLocked(
+ Secure.SHOW_ZEN_SETTINGS_SUGGESTION);
+ if (currentShowZenSettingSuggestion.isNull()) {
+ secureSettings.insertSettingLocked(
+ Secure.SHOW_ZEN_SETTINGS_SUGGESTION, "1",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ // ZEN_SETTINGS_UPDATED
+ final Setting currentUpdatedSetting = secureSettings.getSettingLocked(
+ Secure.ZEN_SETTINGS_UPDATED);
+ if (currentUpdatedSetting.isNull()) {
+ secureSettings.insertSettingLocked(
+ Secure.ZEN_SETTINGS_UPDATED, "0",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ // ZEN_SETTINGS_SUGGESTION_VIEWED
+ final Setting currentSettingSuggestionViewed = secureSettings.getSettingLocked(
+ Secure.ZEN_SETTINGS_SUGGESTION_VIEWED);
+ if (currentSettingSuggestionViewed.isNull()) {
+ secureSettings.insertSettingLocked(
+ Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, "0",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
currentVersion = 170;
}
+ if (currentVersion == 170) {
+ // Version 170: Set the default value for Secure Settings:
+ // CHARGING_SOUNDS_ENABLED and CHARGING_VIBRATION_ENABLED
+
+ final SettingsState globalSettings = getGlobalSettingsLocked();
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+
+ // CHARGING_SOUNDS_ENABLED
+ final Setting globalChargingSoundEnabled = globalSettings.getSettingLocked(
+ Global.CHARGING_SOUNDS_ENABLED);
+ final Setting secureChargingSoundsEnabled = secureSettings.getSettingLocked(
+ Secure.CHARGING_SOUNDS_ENABLED);
+
+ if (!globalChargingSoundEnabled.isNull()) {
+ secureSettings.insertSettingLocked(
+ Secure.CHARGING_SOUNDS_ENABLED,
+ globalChargingSoundEnabled.getValue(), null, false,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+
+ // set global charging_sounds_enabled setting to null since it's deprecated
+ globalSettings.insertSettingLocked(
+ Global.CHARGING_SOUNDS_ENABLED, null, null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
+ } else if (secureChargingSoundsEnabled.isNull()) {
+ String defChargingSoundsEnabled = getContext().getResources()
+ .getBoolean(R.bool.def_charging_sounds_enabled) ? "1" : "0";
+ secureSettings.insertSettingLocked(
+ Secure.CHARGING_SOUNDS_ENABLED, defChargingSoundsEnabled, null,
+ true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ // CHARGING_VIBRATION_ENABLED
+ final Setting secureChargingVibrationEnabled = secureSettings.getSettingLocked(
+ Secure.CHARGING_VIBRATION_ENABLED);
+
+ if (secureChargingVibrationEnabled.isNull()) {
+ String defChargingVibrationEnabled = getContext().getResources()
+ .getBoolean(R.bool.def_charging_vibration_enabled) ? "1" : "0";
+ secureSettings.insertSettingLocked(
+ Secure.CHARGING_VIBRATION_ENABLED, defChargingVibrationEnabled,
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ currentVersion = 171;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 449946d..e57483a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -293,7 +293,7 @@
}
// The settings provider must hold its lock when calling here.
- public void onPackageRemovedLocked(String packageName) {
+ public void removeSettingsForPackageLocked(String packageName) {
boolean removedSomething = false;
final int settingCount = mSettings.size();
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index d80e4ff..33c5551 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -162,7 +162,7 @@
Draws decorations about the screen in software (e.g. rounded corners, cutouts).
-### [com.android.systemui.fingerprint.FingerprintDialogImpl](/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java)
+### [com.android.systemui.biometrics.BiometricDialogImpl](/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java)
Fingerprint UI.
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index e6452e7..fa4c8b5 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -39,6 +39,6 @@
-keep class ** extends androidx.preference.PreferenceFragment
-keep class com.android.systemui.tuner.*
-keep class com.android.systemui.plugins.** {
- public protected *;
+ *;
}
-keep class androidx.core.app.CoreComponentFactory
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index 8379dbb..ee8d357 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -28,7 +28,7 @@
<ImageView android:id="@+id/user_avatar"
android:layout_width="@dimen/car_user_switcher_image_avatar_size"
android:layout_height="@dimen/car_user_switcher_image_avatar_size"
- android:background="@drawable/car_button_ripple_background_inverse"
+ android:background="@drawable/car_button_ripple_background_light"
android:gravity="center"/>
<TextView android:id="@+id/user_name"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index aecf494..19492a0 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -354,7 +354,7 @@
<item>com.android.systemui.LatencyTester</item>
<item>com.android.systemui.globalactions.GlobalActionsComponent</item>
<item>com.android.systemui.ScreenDecorations</item>
- <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
+ <item>com.android.systemui.biometrics.BiometricDialogImpl</item>
<item>com.android.systemui.SliceBroadcastRelayHandler</item>
</string-array>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
index 4bf3500..23582d4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
@@ -34,7 +34,7 @@
* Gets a specific entry in the cache with the specified key, regardless of whether the cached
* value is valid or not.
*/
- final V get(TaskKey key) {
+ final synchronized V get(TaskKey key) {
return getCacheEntry(key.id);
}
@@ -42,7 +42,7 @@
* Returns the value only if the key is valid (has not been updated since the last time it was
* in the cache)
*/
- final V getAndInvalidateIfModified(TaskKey key) {
+ final synchronized V getAndInvalidateIfModified(TaskKey key) {
TaskKey lastKey = mKeys.get(key.id);
if (lastKey != null) {
if ((lastKey.windowingMode != key.windowingMode) ||
@@ -59,7 +59,7 @@
}
/** Puts an entry in the cache for a specific key. */
- final void put(TaskKey key, V value) {
+ final synchronized void put(TaskKey key, V value) {
if (key == null || value == null) {
Log.e(TAG, "Unexpected null key or value: " + key + ", " + value);
return;
@@ -70,14 +70,14 @@
/** Removes a cache entry for a specific key. */
- final void remove(TaskKey key) {
+ final synchronized void remove(TaskKey key) {
// Remove the key after the cache value because we need it to make the callback
removeCacheEntry(key.id);
mKeys.remove(key.id);
}
/** Removes all the entries in the cache. */
- final void evictAll() {
+ final synchronized void evictAll() {
evictAllCache();
mKeys.clear();
}
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 3ac6705..d5383b97 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -146,6 +146,7 @@
getContext().getContentResolver().registerContentObserver(
Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mSettingObserver,
newUserId);
+ updateShowPercent();
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
similarity index 63%
rename from packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
rename to packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
index a81043e..6e62b0d 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.systemui.fingerprint;
+package com.android.systemui.biometrics;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -31,25 +31,28 @@
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.CommandQueue;
-public class FingerprintDialogImpl extends SystemUI implements CommandQueue.Callbacks {
+/**
+ * Receives messages sent from AuthenticationClient and shows the appropriate biometric UI (e.g.
+ * FingerprintDialogView).
+ */
+public class BiometricDialogImpl extends SystemUI implements CommandQueue.Callbacks {
private static final String TAG = "FingerprintDialogImpl";
private static final boolean DEBUG = true;
- protected static final int MSG_SHOW_DIALOG = 1;
- protected static final int MSG_FINGERPRINT_AUTHENTICATED = 2;
- protected static final int MSG_FINGERPRINT_HELP = 3;
- protected static final int MSG_FINGERPRINT_ERROR = 4;
- protected static final int MSG_HIDE_DIALOG = 5;
- protected static final int MSG_BUTTON_NEGATIVE = 6;
- protected static final int MSG_USER_CANCELED = 7;
- protected static final int MSG_BUTTON_POSITIVE = 8;
- protected static final int MSG_CLEAR_MESSAGE = 9;
-
+ private static final int MSG_SHOW_DIALOG = 1;
+ private static final int MSG_BIOMETRIC_AUTHENTICATED = 2;
+ private static final int MSG_BIOMETRIC_HELP = 3;
+ private static final int MSG_BIOMETRIC_ERROR = 4;
+ private static final int MSG_HIDE_DIALOG = 5;
+ private static final int MSG_BUTTON_NEGATIVE = 6;
+ private static final int MSG_USER_CANCELED = 7;
+ private static final int MSG_BUTTON_POSITIVE = 8;
private FingerprintDialogView mDialogView;
private WindowManager mWindowManager;
private IBiometricPromptReceiver mReceiver;
private boolean mDialogShowing;
+ private Callback mCallback = new Callback();
private Handler mHandler = new Handler() {
@Override
@@ -58,14 +61,14 @@
case MSG_SHOW_DIALOG:
handleShowDialog((SomeArgs) msg.obj);
break;
- case MSG_FINGERPRINT_AUTHENTICATED:
- handleFingerprintAuthenticated();
+ case MSG_BIOMETRIC_AUTHENTICATED:
+ handleBiometricAuthenticated();
break;
- case MSG_FINGERPRINT_HELP:
- handleFingerprintHelp((String) msg.obj);
+ case MSG_BIOMETRIC_HELP:
+ handleBiometricHelp((String) msg.obj);
break;
- case MSG_FINGERPRINT_ERROR:
- handleFingerprintError((String) msg.obj);
+ case MSG_BIOMETRIC_ERROR:
+ handleBiometricError((String) msg.obj);
break;
case MSG_HIDE_DIALOG:
handleHideDialog((Boolean) msg.obj);
@@ -79,13 +82,33 @@
case MSG_BUTTON_POSITIVE:
handleButtonPositive();
break;
- case MSG_CLEAR_MESSAGE:
- handleClearMessage();
- break;
}
}
};
+ private class Callback implements DialogViewCallback {
+ @Override
+ public void onUserCanceled() {
+ mHandler.obtainMessage(BiometricDialogImpl.MSG_USER_CANCELED).sendToTarget();
+ }
+
+ @Override
+ public void onErrorShown() {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_HIDE_DIALOG,
+ false /* userCanceled */), BiometricPrompt.HIDE_DIALOG_DELAY);
+ }
+
+ @Override
+ public void onNegativePressed() {
+ mHandler.obtainMessage(BiometricDialogImpl.MSG_BUTTON_NEGATIVE).sendToTarget();
+ }
+
+ @Override
+ public void onPositivePressed() {
+ mHandler.obtainMessage(BiometricDialogImpl.MSG_BUTTON_POSITIVE).sendToTarget();
+ }
+ }
+
@Override
public void start() {
if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
@@ -93,16 +116,16 @@
}
getComponent(CommandQueue.class).addCallbacks(this);
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- mDialogView = new FingerprintDialogView(mContext, mHandler);
+ mDialogView = new FingerprintDialogView(mContext, mCallback);
}
@Override
- public void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
- if (DEBUG) Log.d(TAG, "showFingerprintDialog");
+ public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
+ if (DEBUG) Log.d(TAG, "showBiometricDialog");
// Remove these messages as they are part of the previous client
- mHandler.removeMessages(MSG_FINGERPRINT_ERROR);
- mHandler.removeMessages(MSG_FINGERPRINT_HELP);
- mHandler.removeMessages(MSG_FINGERPRINT_AUTHENTICATED);
+ mHandler.removeMessages(MSG_BIOMETRIC_ERROR);
+ mHandler.removeMessages(MSG_BIOMETRIC_HELP);
+ mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED);
SomeArgs args = SomeArgs.obtain();
args.arg1 = bundle;
args.arg2 = receiver;
@@ -110,26 +133,26 @@
}
@Override
- public void onFingerprintAuthenticated() {
- if (DEBUG) Log.d(TAG, "onFingerprintAuthenticated");
- mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget();
+ public void onBiometricAuthenticated() {
+ if (DEBUG) Log.d(TAG, "onBiometricAuthenticated");
+ mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget();
}
@Override
- public void onFingerprintHelp(String message) {
- if (DEBUG) Log.d(TAG, "onFingerprintHelp: " + message);
- mHandler.obtainMessage(MSG_FINGERPRINT_HELP, message).sendToTarget();
+ public void onBiometricHelp(String message) {
+ if (DEBUG) Log.d(TAG, "onBiometricHelp: " + message);
+ mHandler.obtainMessage(MSG_BIOMETRIC_HELP, message).sendToTarget();
}
@Override
- public void onFingerprintError(String error) {
- if (DEBUG) Log.d(TAG, "onFingerprintError: " + error);
- mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, error).sendToTarget();
+ public void onBiometricError(String error) {
+ if (DEBUG) Log.d(TAG, "onBiometricError: " + error);
+ mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, error).sendToTarget();
}
@Override
- public void hideFingerprintDialog() {
- if (DEBUG) Log.d(TAG, "hideFingerprintDialog");
+ public void hideBiometricDialog() {
+ if (DEBUG) Log.d(TAG, "hideBiometricDialog");
mHandler.obtainMessage(MSG_HIDE_DIALOG, false /* userCanceled */).sendToTarget();
}
@@ -148,21 +171,23 @@
mDialogShowing = true;
}
- private void handleFingerprintAuthenticated() {
- if (DEBUG) Log.d(TAG, "handleFingerprintAuthenticated");
+ private void handleBiometricAuthenticated() {
+ if (DEBUG) Log.d(TAG, "handleBiometricAuthenticated");
+
+ // TODO: announce correct string depending on modality
mDialogView.announceForAccessibility(
mContext.getResources().getText(
com.android.internal.R.string.fingerprint_authenticated));
handleHideDialog(false /* userCanceled */);
}
- private void handleFingerprintHelp(String message) {
- if (DEBUG) Log.d(TAG, "handleFingerprintHelp: " + message);
+ private void handleBiometricHelp(String message) {
+ if (DEBUG) Log.d(TAG, "handleBiometricHelp: " + message);
mDialogView.showHelpMessage(message);
}
- private void handleFingerprintError(String error) {
- if (DEBUG) Log.d(TAG, "handleFingerprintError: " + error);
+ private void handleBiometricError(String error) {
+ if (DEBUG) Log.d(TAG, "handleBiometricError: " + error);
if (!mDialogShowing) {
if (DEBUG) Log.d(TAG, "Dialog already dismissed");
return;
@@ -216,10 +241,6 @@
handleHideDialog(false /* userCanceled */);
}
- private void handleClearMessage() {
- mDialogView.resetMessage();
- }
-
private void handleUserCanceled() {
handleHideDialog(true /* userCanceled */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/DialogViewCallback.java b/packages/SystemUI/src/com/android/systemui/biometrics/DialogViewCallback.java
new file mode 100644
index 0000000..f388d9c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/DialogViewCallback.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.biometrics;
+
+/**
+ * Callback interface for dialog views. These should be implemented by the controller (e.g.
+ * FingerprintDialogImpl) and passed into their views (e.g. FingerprintDialogView).
+ */
+public interface DialogViewCallback {
+ /**
+ * Invoked when the user cancels authentication by tapping outside the prompt, etc. The dialog
+ * should be dismissed.
+ */
+ void onUserCanceled();
+
+ /**
+ * Invoked when an error is shown. The dialog should be dismissed after a set amount of time.
+ */
+ void onErrorShown();
+
+ /**
+ * Invoked when the negative button is pressed. The client should be notified and the dialog
+ * should be dismissed.
+ */
+ void onNegativePressed();
+
+ /**
+ * Invoked when the positive button is pressed. The client should be notified and the dialog
+ * should be dismissed.
+ */
+ void onPositivePressed();
+}
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
rename to packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
index 8013a9e..68c2c42 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FingerprintDialogView.java
@@ -14,7 +14,7 @@
* limitations under the License
*/
-package com.android.systemui.fingerprint;
+package com.android.systemui.biometrics;
import android.content.Context;
import android.graphics.Color;
@@ -26,6 +26,7 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
+import android.os.Message;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -56,6 +57,8 @@
private static final int ANIMATION_DURATION_SHOW = 250; // ms
private static final int ANIMATION_DURATION_AWAY = 350; // ms
+ private static final int MSG_CLEAR_MESSAGE = 1;
+
private static final int STATE_NONE = 0;
private static final int STATE_FINGERPRINT = 1;
private static final int STATE_FINGERPRINT_ERROR = 2;
@@ -68,18 +71,17 @@
private final int mErrorColor;
private final int mTextColor;
private final int mFingerprintColor;
+ private final float mDisplayWidth;
+ private final DialogViewCallback mCallback;
private ViewGroup mLayout;
private final TextView mErrorText;
- private Handler mHandler;
private Bundle mBundle;
private final LinearLayout mDialog;
private int mLastState;
private boolean mAnimatingAway;
private boolean mWasForceRemoved;
- private final float mDisplayWidth;
-
private final Runnable mShowAnimationRunnable = new Runnable() {
@Override
public void run() {
@@ -98,9 +100,23 @@
}
};
- public FingerprintDialogView(Context context, Handler handler) {
+ private Handler mHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ switch(msg.what) {
+ case MSG_CLEAR_MESSAGE:
+ handleClearMessage();
+ break;
+ default:
+ Log.e(TAG, "Unhandled message: " + msg.what);
+ break;
+ }
+ }
+ };
+
+ public FingerprintDialogView(Context context, DialogViewCallback callback) {
super(context);
- mHandler = handler;
+ mCallback = callback;
mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mAnimationTranslationOffset = getResources()
@@ -138,7 +154,7 @@
downPressed = false;
} else if (event.getAction() == KeyEvent.ACTION_UP && downPressed == true) {
downPressed = false;
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_USER_CANCELED).sendToTarget();
+ mCallback.onUserCanceled();
}
return true;
}
@@ -155,11 +171,11 @@
setDismissesDialog(rightSpace);
negative.setOnClickListener((View v) -> {
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_BUTTON_NEGATIVE).sendToTarget();
+ mCallback.onNegativePressed();
});
positive.setOnClickListener((View v) -> {
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_BUTTON_POSITIVE).sendToTarget();
+ mCallback.onPositivePressed();
});
mLayout.setFocusableInTouchMode(true);
@@ -230,8 +246,7 @@
private void setDismissesDialog(View v) {
v.setClickable(true);
v.setOnTouchListener((View view, MotionEvent event) -> {
- mHandler.obtainMessage(FingerprintDialogImpl.MSG_HIDE_DIALOG, true /* userCanceled */)
- .sendToTarget();
+ mCallback.onUserCanceled();
return true;
});
}
@@ -289,7 +304,7 @@
}
// Clears the temporary message and shows the help message.
- protected void resetMessage() {
+ private void handleClearMessage() {
updateFingerprintIcon(STATE_FINGERPRINT);
mErrorText.setText(R.string.fingerprint_dialog_touch_sensor);
mErrorText.setTextColor(mTextColor);
@@ -297,12 +312,12 @@
// Shows an error/help message
private void showTemporaryMessage(String message) {
- mHandler.removeMessages(FingerprintDialogImpl.MSG_CLEAR_MESSAGE);
+ mHandler.removeMessages(MSG_CLEAR_MESSAGE);
updateFingerprintIcon(STATE_FINGERPRINT_ERROR);
mErrorText.setText(message);
mErrorText.setTextColor(mErrorColor);
mErrorText.setContentDescription(message);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(FingerprintDialogImpl.MSG_CLEAR_MESSAGE),
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CLEAR_MESSAGE),
BiometricPrompt.HIDE_DIALOG_DELAY);
}
@@ -312,8 +327,7 @@
public void showErrorMessage(String error) {
showTemporaryMessage(error);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(FingerprintDialogImpl.MSG_HIDE_DIALOG,
- false /* userCanceled */), BiometricPrompt.HIDE_DIALOG_DELAY);
+ mCallback.onErrorShown();
}
private void updateFingerprintIcon(int newState) {
diff --git a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
index 747962f..d5b54f9 100644
--- a/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/charging/WirelessChargingAnimation.java
@@ -111,7 +111,7 @@
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.format = PixelFormat.TRANSLUCENT;
- params.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
+ params.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
params.setTitle("Charging Animation");
params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
index 4bb4e79..36b2347 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenBrightness.java
@@ -23,6 +23,8 @@
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Trace;
+import android.os.UserHandle;
+import android.provider.Settings;
import com.android.internal.annotations.VisibleForTesting;
@@ -111,7 +113,7 @@
int brightness = computeBrightness(mLastSensorValue);
boolean brightnessReady = brightness > 0;
if (brightnessReady) {
- mDozeService.setDozeScreenBrightness(brightness);
+ mDozeService.setDozeScreenBrightness(clampToUserSetting(brightness));
}
int scrimOpacity = -1;
@@ -150,10 +152,17 @@
}
private void resetBrightnessToDefault() {
- mDozeService.setDozeScreenBrightness(mDefaultDozeBrightness);
+ mDozeService.setDozeScreenBrightness(clampToUserSetting(mDefaultDozeBrightness));
mDozeHost.setAodDimmingScrim(0f);
}
+ private int clampToUserSetting(int brightness) {
+ int userSetting = Settings.System.getIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, Integer.MAX_VALUE,
+ UserHandle.USER_CURRENT);
+ return Math.min(brightness, userSetting);
+ }
+
private void setLightSensorEnabled(boolean enabled) {
if (enabled && !mRegistered && mLightSensor != null) {
// Wait until we get an event from the sensor until indicating ready.
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index 3742194..03a573e 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -65,6 +65,7 @@
private static final boolean ENABLE_FLING_DISMISS = false;
private static final int SHOW_DISMISS_AFFORDANCE_DELAY = 225;
+ private static final int BOTTOM_OFFSET_BUFFER_DP = 1;
// Allow dragging the PIP to a location to close it
private final boolean mEnableDimissDragToEdge;
@@ -314,8 +315,10 @@
// above the position as if shelf/IME shows, don't move the PIP window.
int movementBoundsAdjustment = toMovementBounds.bottom - mMovementBounds.bottom;
int offsetAdjustment = fromImeAdjustment ? mImeOffset : mShelfHeight;
+ final float bottomOffsetBufferInPx = BOTTOM_OFFSET_BUFFER_DP
+ * mContext.getResources().getDisplayMetrics().density;
if (toAdjustedBounds.bottom >= mMovementBounds.bottom
- && animatingBounds.top
+ && animatingBounds.top + Math.round(bottomOffsetBufferInPx)
< toAdjustedBounds.bottom - movementBoundsAdjustment - offsetAdjustment) {
return;
}
@@ -514,7 +517,7 @@
* Sets the menu visibility.
*/
private void setMenuState(int menuState, boolean resize) {
- if (menuState == MENU_STATE_FULL) {
+ if (menuState == MENU_STATE_FULL && mMenuState != MENU_STATE_FULL) {
// Save the current snap fraction and if we do not drag or move the PiP, then
// we store back to this snap fraction. Otherwise, we'll reset the snap
// fraction and snap to the closest edge
@@ -523,7 +526,7 @@
mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
mMovementBounds, mExpandedMovementBounds);
}
- } else if (menuState == MENU_STATE_NONE) {
+ } else if (menuState == MENU_STATE_NONE && mMenuState == MENU_STATE_FULL) {
// Try and restore the PiP to the closest edge, using the saved snap fraction
// if possible
if (resize) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index d1e33d3..f523196 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -142,14 +142,14 @@
@Override
public void showDetail(boolean show) {
- int zenDuration = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.ZEN_DURATION, 0);
- boolean showOnboarding = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 0) != 0;
+ int zenDuration = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ZEN_DURATION, 0);
+ boolean showOnboarding = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0) != 0;
if (showOnboarding) {
// don't show on-boarding again or notification ever
- Settings.Global.putInt(mContext.getContentResolver(),
- Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
// turn on DND
mController.setZen(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, TAG);
// show on-boarding screen
@@ -158,7 +158,7 @@
Dependency.get(ActivityStarter.class).postStartActivityDismissingKeyguard(intent, 0);
} else {
switch (zenDuration) {
- case Settings.Global.ZEN_DURATION_PROMPT:
+ case Settings.Secure.ZEN_DURATION_PROMPT:
mUiHandler.post(() -> {
Dialog mDialog = new EnableZenModeDialog(mContext).createDialog();
mDialog.getWindow().setType(
@@ -170,7 +170,7 @@
mHost.collapsePanels();
});
break;
- case Settings.Global.ZEN_DURATION_FOREVER:
+ case Settings.Secure.ZEN_DURATION_FOREVER:
mController.setZen(Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, TAG);
break;
default:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 145a246..909cd79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -85,11 +85,11 @@
private static final int MSG_SHOW_SHUTDOWN_UI = 36 << MSG_SHIFT;
private static final int MSG_SET_TOP_APP_HIDES_STATUS_BAR = 37 << MSG_SHIFT;
private static final int MSG_ROTATION_PROPOSAL = 38 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_SHOW = 39 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_AUTHENTICATED = 40 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_HELP = 41 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_ERROR = 42 << MSG_SHIFT;
- private static final int MSG_FINGERPRINT_HIDE = 43 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_SHOW = 39 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_AUTHENTICATED = 40 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_HELP = 41 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_ERROR = 42 << MSG_SHIFT;
+ private static final int MSG_BIOMETRIC_HIDE = 43 << MSG_SHIFT;
private static final int MSG_SHOW_CHARGING_ANIMATION = 44 << MSG_SHIFT;
private static final int MSG_SHOW_PINNING_TOAST_ENTER_EXIT = 45 << MSG_SHIFT;
private static final int MSG_SHOW_PINNING_TOAST_ESCAPE = 46 << MSG_SHIFT;
@@ -160,11 +160,11 @@
default void onRotationProposal(int rotation, boolean isValid) { }
- default void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) { }
- default void onFingerprintAuthenticated() { }
- default void onFingerprintHelp(String message) { }
- default void onFingerprintError(String error) { }
- default void hideFingerprintDialog() { }
+ default void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) { }
+ default void onBiometricAuthenticated() { }
+ default void onBiometricHelp(String message) { }
+ default void onBiometricError(String error) { }
+ default void hideBiometricDialog() { }
}
@VisibleForTesting
@@ -513,41 +513,41 @@
}
@Override
- public void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
+ public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
synchronized (mLock) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = bundle;
args.arg2 = receiver;
- mHandler.obtainMessage(MSG_FINGERPRINT_SHOW, args)
+ mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args)
.sendToTarget();
}
}
@Override
- public void onFingerprintAuthenticated() {
+ public void onBiometricAuthenticated() {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATED).sendToTarget();
}
}
@Override
- public void onFingerprintHelp(String message) {
+ public void onBiometricHelp(String message) {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_HELP, message).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_HELP, message).sendToTarget();
}
}
@Override
- public void onFingerprintError(String error) {
+ public void onBiometricError(String error) {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, error).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_ERROR, error).sendToTarget();
}
}
@Override
- public void hideFingerprintDialog() {
+ public void hideBiometricDialog() {
synchronized (mLock) {
- mHandler.obtainMessage(MSG_FINGERPRINT_HIDE).sendToTarget();
+ mHandler.obtainMessage(MSG_BIOMETRIC_HIDE).sendToTarget();
}
}
@@ -752,34 +752,34 @@
mCallbacks.get(i).onRotationProposal(msg.arg1, msg.arg2 != 0);
}
break;
- case MSG_FINGERPRINT_SHOW:
- mHandler.removeMessages(MSG_FINGERPRINT_ERROR);
- mHandler.removeMessages(MSG_FINGERPRINT_HELP);
- mHandler.removeMessages(MSG_FINGERPRINT_AUTHENTICATED);
+ case MSG_BIOMETRIC_SHOW:
+ mHandler.removeMessages(MSG_BIOMETRIC_ERROR);
+ mHandler.removeMessages(MSG_BIOMETRIC_HELP);
+ mHandler.removeMessages(MSG_BIOMETRIC_AUTHENTICATED);
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).showFingerprintDialog(
+ mCallbacks.get(i).showBiometricDialog(
(Bundle)((SomeArgs)msg.obj).arg1,
(IBiometricPromptReceiver)((SomeArgs)msg.obj).arg2);
}
break;
- case MSG_FINGERPRINT_AUTHENTICATED:
+ case MSG_BIOMETRIC_AUTHENTICATED:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onFingerprintAuthenticated();
+ mCallbacks.get(i).onBiometricAuthenticated();
}
break;
- case MSG_FINGERPRINT_HELP:
+ case MSG_BIOMETRIC_HELP:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onFingerprintHelp((String) msg.obj);
+ mCallbacks.get(i).onBiometricHelp((String) msg.obj);
}
break;
- case MSG_FINGERPRINT_ERROR:
+ case MSG_BIOMETRIC_ERROR:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).onFingerprintError((String) msg.obj);
+ mCallbacks.get(i).onBiometricError((String) msg.obj);
}
break;
- case MSG_FINGERPRINT_HIDE:
+ case MSG_BIOMETRIC_HIDE:
for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).hideFingerprintDialog();
+ mCallbacks.get(i).hideBiometricDialog();
}
break;
case MSG_SHOW_CHARGING_ANIMATION:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
index 92bf821..47b7fe9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationUiAdjustment.java
@@ -27,6 +27,7 @@
import androidx.annotation.VisibleForTesting;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -38,18 +39,21 @@
public final String key;
public final List<Notification.Action> smartActions;
+ public final CharSequence[] smartReplies;
@VisibleForTesting
- NotificationUiAdjustment(String key, List<Notification.Action> smartActions) {
+ NotificationUiAdjustment(
+ String key, List<Notification.Action> smartActions, CharSequence[] smartReplies) {
this.key = key;
this.smartActions = smartActions == null
? Collections.emptyList()
: new ArrayList<>(smartActions);
+ this.smartReplies = smartReplies == null ? new CharSequence[0] : smartReplies.clone();
}
public static NotificationUiAdjustment extractFromNotificationEntry(
NotificationData.Entry entry) {
- return new NotificationUiAdjustment(entry.key, entry.smartActions);
+ return new NotificationUiAdjustment(entry.key, entry.smartActions, entry.smartReplies);
}
public static boolean needReinflate(
@@ -58,7 +62,13 @@
if (oldAdjustment == newAdjustment) {
return false;
}
- return areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions);
+ if (areDifferent(oldAdjustment.smartActions, newAdjustment.smartActions)) {
+ return true;
+ }
+ if (!Arrays.equals(oldAdjustment.smartReplies, newAdjustment.smartReplies)) {
+ return true;
+ }
+ return false;
}
public static boolean areDifferent(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
index 81d6191..32fd054 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
@@ -147,7 +147,7 @@
return;
}
view.setTemp(mHvacManager.getFloatProperty(id, zone));
- } catch (CarNotConnectedException e) {
+ } catch (Exception e) {
view.setTemp(Float.NaN);
Log.e(TAG, "Failed to get value from hvac service", e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
index ce8f224..804e842 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
@@ -112,6 +112,7 @@
public int userSentiment = Ranking.USER_SENTIMENT_NEUTRAL;
@NonNull
public List<Notification.Action> smartActions = Collections.emptyList();
+ public CharSequence[] smartReplies = new CharSequence[0];
private int mCachedContrastColor = COLOR_INVALID;
private int mCachedContrastColorIsFor = COLOR_INVALID;
@@ -155,6 +156,9 @@
userSentiment = ranking.getUserSentiment();
smartActions = ranking.getSmartActions() == null
? Collections.emptyList() : ranking.getSmartActions();
+ smartReplies = ranking.getSmartReplies() == null
+ ? new CharSequence[0]
+ : ranking.getSmartReplies().toArray(new CharSequence[0]);
}
public void setInterruption() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index da1fd3b..0110610 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -36,6 +36,7 @@
import android.widget.LinearLayout;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -1229,32 +1230,40 @@
boolean hasRemoteInput = false;
RemoteInput remoteInputWithChoices = null;
PendingIntent pendingIntentWithChoices = null;
+ CharSequence[] choices = null;
Notification.Action[] actions = entry.notification.getNotification().actions;
if (actions != null) {
for (Notification.Action a : actions) {
- if (a.getRemoteInputs() != null) {
- for (RemoteInput ri : a.getRemoteInputs()) {
- boolean showRemoteInputView = ri.getAllowFreeFormInput();
- boolean showSmartReplyView = enableSmartReplies && ri.getChoices() != null
- && ri.getChoices().length > 0;
- if (showRemoteInputView) {
- hasRemoteInput = true;
+ if (a.getRemoteInputs() == null) {
+ continue;
+ }
+ for (RemoteInput ri : a.getRemoteInputs()) {
+ boolean showRemoteInputView = ri.getAllowFreeFormInput();
+ boolean showSmartReplyView = enableSmartReplies
+ && (ArrayUtils.isEmpty(ri.getChoices())
+ || (showRemoteInputView && !ArrayUtils.isEmpty(entry.smartReplies)));
+ if (showRemoteInputView) {
+ hasRemoteInput = true;
+ }
+ if (showSmartReplyView) {
+ remoteInputWithChoices = ri;
+ pendingIntentWithChoices = a.actionIntent;
+ if (!ArrayUtils.isEmpty(ri.getChoices())) {
+ choices = ri.getChoices();
+ } else {
+ choices = entry.smartReplies;
}
- if (showSmartReplyView) {
- remoteInputWithChoices = ri;
- pendingIntentWithChoices = a.actionIntent;
- }
- if (showRemoteInputView || showSmartReplyView) {
- break;
- }
+ }
+ if (showRemoteInputView || showSmartReplyView) {
+ break;
}
}
}
}
applyRemoteInput(entry, hasRemoteInput);
- applySmartReplyView(remoteInputWithChoices, pendingIntentWithChoices, entry);
+ applySmartReplyView(remoteInputWithChoices, pendingIntentWithChoices, entry, choices);
}
private void applyRemoteInput(NotificationData.Entry entry, boolean hasRemoteInput) {
@@ -1356,10 +1365,10 @@
}
private void applySmartReplyView(RemoteInput remoteInput, PendingIntent pendingIntent,
- NotificationData.Entry entry) {
+ NotificationData.Entry entry, CharSequence[] choices) {
if (mExpandedChild != null) {
mExpandedSmartReplyView =
- applySmartReplyView(mExpandedChild, remoteInput, pendingIntent, entry);
+ applySmartReplyView(mExpandedChild, remoteInput, pendingIntent, entry, choices);
if (mExpandedSmartReplyView != null && remoteInput != null
&& remoteInput.getChoices() != null && remoteInput.getChoices().length > 0) {
mSmartReplyController.smartRepliesAdded(entry, remoteInput.getChoices().length);
@@ -1369,7 +1378,7 @@
private SmartReplyView applySmartReplyView(
View view, RemoteInput remoteInput, PendingIntent pendingIntent,
- NotificationData.Entry entry) {
+ NotificationData.Entry entry, CharSequence[] choices) {
View smartReplyContainerCandidate = view.findViewById(
com.android.internal.R.id.smart_reply_container);
if (!(smartReplyContainerCandidate instanceof LinearLayout)) {
@@ -1406,7 +1415,8 @@
}
if (smartReplyView != null) {
smartReplyView.setRepliesFromRemoteInput(remoteInput, pendingIntent,
- mSmartReplyController, entry, smartReplyContainer);
+ mSmartReplyController, entry, smartReplyContainer, choices
+ );
smartReplyContainer.setVisibility(View.VISIBLE);
}
return smartReplyView;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index c400893..4c91a9d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -516,7 +516,7 @@
}
WallpaperInfo info = wallpaperManager.getWallpaperInfo(UserHandle.USER_CURRENT);
final boolean supportsAmbientMode = info != null &&
- info.getSupportsAmbientMode();
+ info.supportsAmbientMode();
mStatusBarWindowManager.setWallpaperSupportsAmbientMode(supportsAmbientMode);
mScrimController.setWallpaperSupportsAmbientMode(supportsAmbientMode);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 252ab22..c76a4b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -173,14 +173,14 @@
Math.max(getChildCount(), 1), DECREASING_MEASURED_WIDTH_WITHOUT_PADDING_COMPARATOR);
}
- public void setRepliesFromRemoteInput(RemoteInput remoteInput, PendingIntent pendingIntent,
+ public void setRepliesFromRemoteInput(
+ RemoteInput remoteInput, PendingIntent pendingIntent,
SmartReplyController smartReplyController, NotificationData.Entry entry,
- View smartReplyContainer) {
+ View smartReplyContainer, CharSequence[] choices) {
mSmartReplyContainer = smartReplyContainer;
removeAllViews();
mCurrentBackgroundColor = mDefaultBackgroundColor;
if (remoteInput != null && pendingIntent != null) {
- CharSequence[] choices = remoteInput.getChoices();
if (choices != null) {
for (int i = 0; i < choices.length; ++i) {
Button replyButton = inflateReplyButton(
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 7855b47..02babac 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -148,6 +148,7 @@
private SafetyWarningDialog mSafetyWarning;
private boolean mHovering = false;
private boolean mShowActiveStreamOnly;
+ private boolean mConfigChanged = false;
public VolumeDialogImpl(Context context) {
mContext = new ContextThemeWrapper(context, com.android.systemui.R.style.qs_theme);
@@ -551,6 +552,11 @@
rescheduleTimeoutH();
mShowing = true;
+ if (mConfigChanged) {
+ initDialog();
+ mConfigurableTexts.update();
+ mConfigChanged = false;
+ }
initSettingsH();
mDialog.show();
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
@@ -1102,8 +1108,7 @@
@Override
public void onConfigurationChanged() {
mDialog.dismiss();
- initDialog();
- mConfigurableTexts.update();
+ mConfigChanged = true;
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
index 5e12781..eaa0dcf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeScreenBrightnessTest.java
@@ -34,6 +34,8 @@
import static org.junit.Assert.assertTrue;
import android.os.PowerManager;
+import android.os.UserHandle;
+import android.provider.Settings;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
@@ -60,6 +62,9 @@
@Before
public void setUp() throws Exception {
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, DEFAULT_BRIGHTNESS,
+ UserHandle.USER_CURRENT);
mServiceFake = new DozeServiceFake();
mHostFake = new DozeHostFake();
mSensorManager = new FakeSensorManager(mContext);
@@ -88,6 +93,17 @@
}
@Test
+ public void testAod_usesLightSensorRespectingUserSetting() throws Exception {
+ int maxBrightness = 3;
+ Settings.System.putIntForUser(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, maxBrightness,
+ UserHandle.USER_CURRENT);
+
+ mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
+ assertEquals(maxBrightness, mServiceFake.screenBrightness);
+ }
+
+ @Test
public void testPausingAod_doesntPauseLightSensor() throws Exception {
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_AOD);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
index ce47e60..db1e049 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationUiAdjustmentTest.java
@@ -30,6 +30,7 @@
import org.junit.Test;
import java.util.Collections;
+import java.util.List;
@SmallTest
public class NotificationUiAdjustmentTest extends SysuiTestCase {
@@ -41,8 +42,8 @@
Notification.Action action =
createActionBuilder("first", R.drawable.ic_corp_icon, pendingIntent).build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.emptyList()),
- new NotificationUiAdjustment("second", Collections.singletonList(action))))
+ createUiAdjustmentFromSmartActions("first", Collections.emptyList()),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(action))))
.isTrue();
}
@@ -56,8 +57,8 @@
createActionBuilder("second", R.drawable.ic_corp_icon, pendingIntent).build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -72,8 +73,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -91,8 +92,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -116,8 +117,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -141,8 +142,8 @@
.build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions("second", Collections.singletonList(secondAction))))
.isTrue();
}
@@ -163,8 +164,25 @@
.addRemoteInput(secondRemoteInput).build();
assertThat(NotificationUiAdjustment.needReinflate(
- new NotificationUiAdjustment("first", Collections.singletonList(firstAction)),
- new NotificationUiAdjustment("second", Collections.singletonList(secondAction))))
+ createUiAdjustmentFromSmartActions("first", Collections.singletonList(firstAction)),
+ createUiAdjustmentFromSmartActions(
+ "second", Collections.singletonList(secondAction))))
+ .isFalse();
+ }
+
+ @Test
+ public void needReinflate_differentSmartReplies() {
+ assertThat(NotificationUiAdjustment.needReinflate(
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[]{"a", "b"}),
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[] {"b", "a"})))
+ .isTrue();
+ }
+
+ @Test
+ public void needReinflate_sameSmartReplies() {
+ assertThat(NotificationUiAdjustment.needReinflate(
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[] {"a", "b"}),
+ createUiAdjustmentFromSmartReplies("first", new CharSequence[] {"a", "b"})))
.isFalse();
}
@@ -177,4 +195,14 @@
private RemoteInput createRemoteInput(String resultKey, String label, CharSequence[] choices) {
return new RemoteInput.Builder(resultKey).setLabel(label).setChoices(choices).build();
}
+
+ private NotificationUiAdjustment createUiAdjustmentFromSmartActions(
+ String key, List<Notification.Action> actions) {
+ return new NotificationUiAdjustment(key, actions, new CharSequence[0]);
+ }
+
+ private NotificationUiAdjustment createUiAdjustmentFromSmartReplies(
+ String key, CharSequence[] replies) {
+ return new NotificationUiAdjustment(key, Collections.emptyList(), replies);
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
index c3683b3..de5a8a0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
@@ -430,21 +430,22 @@
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
outRanking.canShowBadge(), outRanking.getUserSentiment(), true,
- null);
+ null, null);
} else if (key.equals(TEST_EXEMPT_DND_VISUAL_SUPPRESSION_KEY)) {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
outRanking.getVisibilityOverride(), 255,
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), outRanking.getChannel(), null, null,
- outRanking.canShowBadge(), outRanking.getUserSentiment(), true, null);
+ outRanking.canShowBadge(), outRanking.getUserSentiment(), true, null, null);
} else {
outRanking.populate(key, outRanking.getRank(),
outRanking.matchesInterruptionFilter(),
outRanking.getVisibilityOverride(), outRanking.getSuppressedVisualEffects(),
outRanking.getImportance(), outRanking.getImportanceExplanation(),
outRanking.getOverrideGroupKey(), NOTIFICATION_CHANNEL, null, null,
- outRanking.canShowBadge(), outRanking.getUserSentiment(), false, null);
+ outRanking.canShowBadge(), outRanking.getUserSentiment(), false, null,
+ null);
}
return true;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 61c1ecb..6543bdb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -157,7 +157,7 @@
0,
NotificationManager.IMPORTANCE_DEFAULT,
null, null,
- null, null, null, true, sentiment, false, null);
+ null, null, null, true, sentiment, false, null, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
@@ -176,7 +176,7 @@
null, null,
null, null, null, true,
NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL, false,
- smartActions);
+ smartActions, null);
return true;
}).when(mRankingMap).getRanking(eq(key), any(NotificationListenerService.Ranking.class));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 5ac2190..01e6307 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -375,7 +375,7 @@
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
new Intent(TEST_ACTION), 0);
RemoteInput input = new RemoteInput.Builder(TEST_RESULT_KEY).setChoices(choices).build();
- mView.setRepliesFromRemoteInput(input, pendingIntent, mLogger, mEntry, mContainer);
+ mView.setRepliesFromRemoteInput(input, pendingIntent, mLogger, mEntry, mContainer, choices);
}
/** Builds a {@link ViewGroup} whose measures and layout mirror a {@link SmartReplyView}. */
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 496cd96..02f0439 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -6175,6 +6175,11 @@
// OS: Q
FACE = 1511;
+ // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog
+ // CATEGORY: SETTINGS
+ // OS: Q
+ DIALOG_ACCESSIBILITY_HEARINGAID = 1512;
+
// ---- End Q Constants, all Q constants go above this line ----
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 11b2343..cf08681 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -22,10 +22,8 @@
import android.util.DebugUtils;
import android.util.ExceptionUtils;
import android.util.Log;
-import android.util.Pools.SimplePool;
import android.util.Slog;
import android.util.SparseBooleanArray;
-import android.view.Choreographer;
import android.view.InputDevice;
import android.view.InputEvent;
import android.view.InputFilter;
@@ -104,31 +102,12 @@
| FLAG_FEATURE_AUTOCLICK | FLAG_FEATURE_TOUCH_EXPLORATION
| FLAG_FEATURE_SCREEN_MAGNIFIER | FLAG_FEATURE_TRIGGERED_SCREEN_MAGNIFIER;
- private final Runnable mProcessBatchedEventsRunnable = new Runnable() {
- @Override
- public void run() {
- final long frameTimeNanos = mChoreographer.getFrameTimeNanos();
- if (DEBUG) {
- Slog.i(TAG, "Begin batch processing for frame: " + frameTimeNanos);
- }
- processBatchedEvents(frameTimeNanos);
- if (DEBUG) {
- Slog.i(TAG, "End batch processing.");
- }
- if (mEventQueue != null) {
- scheduleProcessBatchedEvents();
- }
- }
- };
-
private final Context mContext;
private final PowerManager mPm;
private final AccessibilityManagerService mAms;
- private final Choreographer mChoreographer;
-
private boolean mInstalled;
private int mUserId;
@@ -147,8 +126,6 @@
private EventStreamTransformation mEventHandler;
- private MotionEventHolder mEventQueue;
-
private EventStreamState mMouseStreamState;
private EventStreamState mTouchScreenStreamState;
@@ -160,7 +137,6 @@
mContext = context;
mAms = service;
mPm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- mChoreographer = Choreographer.getInstance();
}
@Override
@@ -274,7 +250,7 @@
return;
}
- batchMotionEvent(event, policyFlags);
+ handleMotionEvent(event, policyFlags);
}
private void processKeyEvent(EventStreamState state, KeyEvent event, int policyFlags) {
@@ -285,68 +261,14 @@
mEventHandler.onKeyEvent(event, policyFlags);
}
- private void scheduleProcessBatchedEvents() {
- mChoreographer.postCallback(Choreographer.CALLBACK_INPUT,
- mProcessBatchedEventsRunnable, null);
- }
-
- private void batchMotionEvent(MotionEvent event, int policyFlags) {
- if (DEBUG) {
- Slog.i(TAG, "Batching event: " + event + ", policyFlags: " + policyFlags);
- }
- if (mEventQueue == null) {
- mEventQueue = MotionEventHolder.obtain(event, policyFlags);
- scheduleProcessBatchedEvents();
- return;
- }
- if (mEventQueue.event.addBatch(event)) {
- return;
- }
- MotionEventHolder holder = MotionEventHolder.obtain(event, policyFlags);
- holder.next = mEventQueue;
- mEventQueue.previous = holder;
- mEventQueue = holder;
- }
-
- private void processBatchedEvents(long frameNanos) {
- MotionEventHolder current = mEventQueue;
- if (current == null) {
- return;
- }
- while (current.next != null) {
- current = current.next;
- }
- while (true) {
- if (current == null) {
- mEventQueue = null;
- break;
- }
- if (current.event.getEventTimeNano() >= frameNanos) {
- // Finished with this choreographer frame. Do the rest on the next one.
- current.next = null;
- break;
- }
- handleMotionEvent(current.event, current.policyFlags);
- MotionEventHolder prior = current;
- current = current.previous;
- prior.recycle();
- }
- }
-
private void handleMotionEvent(MotionEvent event, int policyFlags) {
if (DEBUG) {
- Slog.i(TAG, "Handling batched event: " + event + ", policyFlags: " + policyFlags);
+ Slog.i(TAG, "Handling motion event: " + event + ", policyFlags: " + policyFlags);
}
- // Since we do batch processing it is possible that by the time the
- // next batch is processed the event handle had been set to null.
- if (mEventHandler != null) {
- mPm.userActivity(event.getEventTime(), false);
- MotionEvent transformedEvent = MotionEvent.obtain(event);
- mEventHandler.onMotionEvent(transformedEvent, event, policyFlags);
- transformedEvent.recycle();
- } else {
- if (DEBUG) Slog.d(TAG, "mEventHandler == null for " + event);
- }
+ mPm.userActivity(event.getEventTime(), false);
+ MotionEvent transformedEvent = MotionEvent.obtain(event);
+ mEventHandler.onMotionEvent(transformedEvent, event, policyFlags);
+ transformedEvent.recycle();
}
@Override
@@ -469,9 +391,6 @@
}
private void disableFeatures() {
- // Give the features a chance to process any batched events so we'll keep a consistent
- // event stream
- processBatchedEvents(Long.MAX_VALUE);
if (mMotionEventInjector != null) {
mAms.setMotionEventInjector(null);
mMotionEventInjector.onDestroy();
@@ -515,36 +434,6 @@
/* ignore */
}
- private static class MotionEventHolder {
- private static final int MAX_POOL_SIZE = 32;
- private static final SimplePool<MotionEventHolder> sPool =
- new SimplePool<MotionEventHolder>(MAX_POOL_SIZE);
-
- public int policyFlags;
- public MotionEvent event;
- public MotionEventHolder next;
- public MotionEventHolder previous;
-
- public static MotionEventHolder obtain(MotionEvent event, int policyFlags) {
- MotionEventHolder holder = sPool.acquire();
- if (holder == null) {
- holder = new MotionEventHolder();
- }
- holder.event = MotionEvent.obtain(event);
- holder.policyFlags = policyFlags;
- return holder;
- }
-
- public void recycle() {
- event.recycle();
- event = null;
- policyFlags = 0;
- next = null;
- previous = null;
- sPool.release(this);
- }
- }
-
/**
* Keeps state of event streams observed for an input device with a certain source.
* Provides information about whether motion and key events should be processed by accessibility
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 2da0818..9c0e110 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -16,12 +16,18 @@
package com.android.server.accessibility;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_MASK;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.accessibility.AccessibilityEvent.WINDOWS_CHANGE_ACCESSIBILITY_FOCUSED;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS;
import static com.android.internal.util.FunctionalUtils.ignoreRemoteException;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_AUTO;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HIDDEN;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_WITH_HARD_KEYBOARD;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE;
+import static android.accessibilityservice.AccessibilityService.SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN;
import android.Manifest;
import android.accessibilityservice.AccessibilityService;
@@ -1807,7 +1813,6 @@
updateDisplayDaltonizerLocked(userState);
updateDisplayInversionLocked(userState);
updateMagnificationLocked(userState);
- updateSoftKeyboardShowModeLocked(userState);
scheduleUpdateFingerprintGestureHandling(userState);
scheduleUpdateInputFilter(userState);
scheduleUpdateClientsIfNeededLocked(userState);
@@ -2001,18 +2006,6 @@
return false;
}
- private boolean readSoftKeyboardShowModeChangedLocked(UserState userState) {
- final int softKeyboardShowMode = Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0,
- userState.mUserId);
- if (softKeyboardShowMode != userState.mSoftKeyboardShowMode) {
- userState.mSoftKeyboardShowMode = softKeyboardShowMode;
- return true;
- }
- return false;
- }
-
private void updateTouchExplorationLocked(UserState userState) {
boolean enabled = mUiAutomationManager.isTouchExplorationEnabledLocked();
final int serviceCount = userState.mBoundServices.size();
@@ -2211,34 +2204,6 @@
return false;
}
- private void updateSoftKeyboardShowModeLocked(UserState userState) {
- final int userId = userState.mUserId;
- // Only check whether we need to reset the soft keyboard mode if it is not set to the
- // default.
- if ((userId == mCurrentUserId) && (userState.mSoftKeyboardShowMode != 0)) {
- // Check whether the last AccessibilityService that changed the soft keyboard mode to
- // something other than the default is still enabled and, if not, remove flag and
- // reset to the default soft keyboard behavior.
- boolean serviceChangingSoftKeyboardModeIsEnabled =
- userState.mEnabledServices.contains(userState.mServiceChangingSoftKeyboardMode);
-
- if (!serviceChangingSoftKeyboardModeIsEnabled) {
- final long identity = Binder.clearCallingIdentity();
- try {
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
- 0,
- userState.mUserId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- userState.mSoftKeyboardShowMode = 0;
- userState.mServiceChangingSoftKeyboardMode = null;
- notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
- }
- }
- }
-
private void updateFingerprintGestureHandling(UserState userState) {
final List<AccessibilityServiceConnection> services;
synchronized (mLock) {
@@ -2473,6 +2438,15 @@
}
}
+ private void putSecureIntForUser(String key, int value, int userid) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putIntForUser(mContext.getContentResolver(), key, value, userid);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
class RemoteAccessibilityConnection implements DeathRecipient {
private final int mUid;
private final String mPackageName;
@@ -3683,7 +3657,7 @@
public int mLastSentClientState = -1;
- public int mSoftKeyboardShowMode = 0;
+ private int mSoftKeyboardShowMode = 0;
public boolean mIsNavBarMagnificationAssignedToAccessibilityButton;
public ComponentName mServiceAssignedToAccessibilityButton;
@@ -3744,7 +3718,6 @@
mServiceAssignedToAccessibilityButton = null;
mIsNavBarMagnificationAssignedToAccessibilityButton = false;
mIsAutoclickEnabled = false;
- mSoftKeyboardShowMode = 0;
}
public void addServiceLocked(AccessibilityServiceConnection serviceConnection) {
@@ -3766,6 +3739,11 @@
public void removeServiceLocked(AccessibilityServiceConnection serviceConnection) {
mBoundServices.remove(serviceConnection);
serviceConnection.onRemoved();
+ if ((mServiceChangingSoftKeyboardMode != null)
+ && (mServiceChangingSoftKeyboardMode.equals(
+ serviceConnection.getServiceInfo().getComponentName()))) {
+ setSoftKeyboardModeLocked(SHOW_MODE_AUTO, null);
+ }
// It may be possible to bind a service twice, which confuses the map. Rebuild the map
// to make sure we can still reach a service
mComponentNameToServiceMap.clear();
@@ -3792,6 +3770,134 @@
public Set<ComponentName> getBindingServicesLocked() {
return mBindingServices;
}
+
+ public int getSoftKeyboardShowMode() {
+ return mSoftKeyboardShowMode;
+ }
+
+ /**
+ * Set the soft keyboard mode. This mode is a bit odd, as it spans multiple settings.
+ * The ACCESSIBILITY_SOFT_KEYBOARD_MODE setting can be checked by the rest of the system
+ * to see if it should suppress showing the IME. The SHOW_IME_WITH_HARD_KEYBOARD setting
+ * setting can be changed by the user, and prevents the system from suppressing the soft
+ * keyboard when the hard keyboard is connected. The hard keyboard setting needs to defer
+ * to the user's preference, if they have supplied one.
+ *
+ * @param newMode The new mode
+ * @param requester The service requesting the change, so we can undo it when the
+ * service stops. Set to null if something other than a service is forcing
+ * the change.
+ *
+ * @return Whether or not the soft keyboard mode equals the new mode after the call
+ */
+ public boolean setSoftKeyboardModeLocked(int newMode, @Nullable ComponentName requester) {
+ if ((newMode != SHOW_MODE_AUTO) && (newMode != SHOW_MODE_HIDDEN)
+ && (newMode != SHOW_MODE_WITH_HARD_KEYBOARD))
+ {
+ Slog.w(LOG_TAG, "Invalid soft keyboard mode");
+ return false;
+ }
+ if (mSoftKeyboardShowMode == newMode) return true;
+
+ if (newMode == SHOW_MODE_WITH_HARD_KEYBOARD) {
+ if (hasUserOverriddenHardKeyboardSettingLocked()) {
+ // The user has specified a default for this setting
+ return false;
+ }
+ // Save the original value. But don't do this if the value in settings is already
+ // the new mode. That happens when we start up after a reboot, and we don't want
+ // to overwrite the value we had from when we first started controlling the setting.
+ if (getSoftKeyboardValueFromSettings() != SHOW_MODE_WITH_HARD_KEYBOARD) {
+ setOriginalHardKeyboardValue(
+ Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0) != 0);
+ }
+ putSecureIntForUser(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 1, mUserId);
+ } else if (mSoftKeyboardShowMode == SHOW_MODE_WITH_HARD_KEYBOARD) {
+ putSecureIntForUser(Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
+ getOriginalHardKeyboardValue() ? 1 : 0, mUserId);
+ }
+
+ saveSoftKeyboardValueToSettings(newMode);
+ mSoftKeyboardShowMode = newMode;
+ mServiceChangingSoftKeyboardMode = requester;
+ notifySoftKeyboardShowModeChangedLocked(mSoftKeyboardShowMode);
+ return true;
+ }
+
+ /**
+ * If the settings are inconsistent with the internal state, make the internal state
+ * match the settings.
+ */
+ public void reconcileSoftKeyboardModeWithSettingsLocked() {
+ final ContentResolver cr = mContext.getContentResolver();
+ final boolean showWithHardKeyboardSettings =
+ Settings.Secure.getInt(cr, Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0) != 0;
+ if (mSoftKeyboardShowMode == SHOW_MODE_WITH_HARD_KEYBOARD) {
+ if (!showWithHardKeyboardSettings) {
+ // The user has overridden the setting. Respect that and prevent further changes
+ // to this behavior.
+ setSoftKeyboardModeLocked(SHOW_MODE_AUTO, null);
+ setUserOverridesHardKeyboardSettingLocked();
+ }
+ }
+
+ // If the setting and the internal state are out of sync, set both to default
+ if (getSoftKeyboardValueFromSettings() != mSoftKeyboardShowMode)
+ {
+ Slog.e(LOG_TAG,
+ "Show IME setting inconsistent with internal state. Overwriting");
+ setSoftKeyboardModeLocked(SHOW_MODE_AUTO, null);
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ SHOW_MODE_AUTO, mUserId);
+ }
+ }
+
+ private void setUserOverridesHardKeyboardSettingLocked() {
+ final int softKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ softKeyboardSetting | SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN,
+ mUserId);
+ }
+
+ private boolean hasUserOverriddenHardKeyboardSettingLocked() {
+ final int softKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ return (softKeyboardSetting & SHOW_MODE_HARD_KEYBOARD_OVERRIDDEN)
+ != 0;
+ }
+
+ private void setOriginalHardKeyboardValue(boolean originalHardKeyboardValue) {
+ final int oldSoftKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ final int newSoftKeyboardSetting = oldSoftKeyboardSetting
+ & (~SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE)
+ | ((originalHardKeyboardValue) ? SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE : 0);
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ newSoftKeyboardSetting, mUserId);
+ }
+
+ private void saveSoftKeyboardValueToSettings(int softKeyboardShowMode) {
+ final int oldSoftKeyboardSetting = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0);
+ final int newSoftKeyboardSetting = oldSoftKeyboardSetting & (~SHOW_MODE_MASK)
+ | softKeyboardShowMode;
+ putSecureIntForUser(Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ newSoftKeyboardSetting, mUserId);
+ }
+
+ private int getSoftKeyboardValueFromSettings() {
+ return Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ SHOW_MODE_AUTO) & SHOW_MODE_MASK;
+ }
+
+ private boolean getOriginalHardKeyboardValue() {
+ return (Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0)
+ & SHOW_MODE_HARD_KEYBOARD_ORIGINAL_VALUE) != 0;
+ }
}
private final class AccessibilityContentObserver extends ContentObserver {
@@ -3829,6 +3935,9 @@
private final Uri mAccessibilitySoftKeyboardModeUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
+ private final Uri mShowImeWithHardKeyboardUri = Settings.Secure.getUriFor(
+ Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD);
+
private final Uri mAccessibilityShortcutServiceIdUri = Settings.Secure.getUriFor(
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
@@ -3864,6 +3973,8 @@
contentResolver.registerContentObserver(
mAccessibilitySoftKeyboardModeUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
+ mShowImeWithHardKeyboardUri, false, this, UserHandle.USER_ALL);
+ contentResolver.registerContentObserver(
mAccessibilityShortcutServiceIdUri, false, this, UserHandle.USER_ALL);
contentResolver.registerContentObserver(
mAccessibilityButtonComponentIdUri, false, this, UserHandle.USER_ALL);
@@ -3906,11 +4017,9 @@
if (readHighTextContrastEnabledSettingLocked(userState)) {
onUserStateChangedLocked(userState);
}
- } else if (mAccessibilitySoftKeyboardModeUri.equals(uri)) {
- if (readSoftKeyboardShowModeChangedLocked(userState)) {
- notifySoftKeyboardShowModeChangedLocked(userState.mSoftKeyboardShowMode);
- onUserStateChangedLocked(userState);
- }
+ } else if (mAccessibilitySoftKeyboardModeUri.equals(uri)
+ || mShowImeWithHardKeyboardUri.equals(uri)) {
+ userState.reconcileSoftKeyboardModeWithSettingsLocked();
} else if (mAccessibilityShortcutServiceIdUri.equals(uri)) {
if (readAccessibilityShortcutSettingLocked(userState)) {
onUserStateChangedLocked(userState);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 8f92145..6237212 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -218,26 +218,20 @@
if (!isCalledForCurrentUserLocked()) {
return false;
}
+ final UserState userState = mUserStateWeakReference.get();
+ if (userState == null) return false;
+ return userState.setSoftKeyboardModeLocked(showMode, mComponentName);
}
- UserState userState = mUserStateWeakReference.get();
- if (userState == null) return false;
- final long identity = Binder.clearCallingIdentity();
- try {
- // Keep track of the last service to request a non-default show mode. The show mode
- // should be restored to default should this service be disabled.
- userState.mServiceChangingSoftKeyboardMode = (showMode == SHOW_MODE_AUTO)
- ? null : mComponentName;
-
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, showMode,
- userState.mUserId);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- return true;
}
@Override
+ public int getSoftKeyboardShowMode() {
+ final UserState userState = mUserStateWeakReference.get();
+ return (userState != null) ? userState.getSoftKeyboardShowMode() : 0;
+ }
+
+
+ @Override
public boolean isAccessibilityButtonAvailable() {
synchronized (mLock) {
if (!isCalledForCurrentUserLocked()) {
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index ed3b3e7..ff29311 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -259,6 +259,11 @@
}
@Override
+ public int getSoftKeyboardShowMode() {
+ return 0;
+ }
+
+ @Override
public boolean isAccessibilityButtonAvailable() {
return false;
}
diff --git a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
index 293f908e..8ee6571 100644
--- a/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
+++ b/services/autofill/java/com/android/server/autofill/FieldClassificationStrategy.java
@@ -17,8 +17,8 @@
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
-import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS;
-import static android.service.autofill.AutofillFieldClassificationService.SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM;
+import static android.service.autofill.AutofillFieldClassificationService.RESOURCE_AVAILABLE_ALGORITHMS;
+import static android.service.autofill.AutofillFieldClassificationService.RESOURCE_DEFAULT_ALGORITHM;
import android.Manifest;
import android.annotation.MainThread;
@@ -226,7 +226,7 @@
*/
@Nullable
String[] getAvailableAlgorithms() {
- return getMetadataValue(SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS,
+ return getMetadataValue(RESOURCE_AVAILABLE_ALGORITHMS, "array",
(res, id) -> res.getStringArray(id));
}
@@ -235,11 +235,12 @@
*/
@Nullable
String getDefaultAlgorithm() {
- return getMetadataValue(SERVICE_META_DATA_KEY_DEFAULT_ALGORITHM, (res, id) -> res.getString(id));
+ return getMetadataValue(RESOURCE_DEFAULT_ALGORITHM, "string",
+ (res, id) -> res.getString(id));
}
@Nullable
- private <T> T getMetadataValue(String field, MetadataParser<T> parser) {
+ private <T> T getMetadataValue(String field, String type, MetadataParser<T> parser) {
final ServiceInfo serviceInfo = getServiceInfo();
if (serviceInfo == null) return null;
@@ -253,7 +254,7 @@
return null;
}
- final int resourceId = serviceInfo.metaData.getInt(field);
+ final int resourceId = res.getIdentifier(field, type, serviceInfo.packageName);
return parser.get(res, resourceId);
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 48c2eae..13de9fa 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -268,7 +268,7 @@
// change AssistStructure so it provides a "one-way" writeToParcel() method that
// sends all the data
try {
- structure.ensureData();
+ structure.ensureDataForAutofill();
} catch (RuntimeException e) {
wtf(e, "Exception lazy loading assist structure for %s: %s",
structure.getActivityComponent(), e);
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
index ae2a36b..30ec8ab 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbBackupEngine.java
@@ -9,6 +9,7 @@
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
+import android.app.backup.IBackupCallback;
import android.app.backup.FullBackup;
import android.app.backup.FullBackupDataOutput;
import android.content.pm.ApplicationInfo;
@@ -20,6 +21,7 @@
import android.util.Slog;
import com.android.internal.util.Preconditions;
+import com.android.server.backup.remote.ServiceBackupCallback;
import com.android.server.backup.utils.FullBackupUtils;
import libcore.io.IoUtils;
@@ -158,10 +160,17 @@
mBackupManagerService.prepareOperationTimeout(token, kvBackupAgentTimeoutMillis, null,
OP_TYPE_BACKUP_WAIT);
+ IBackupCallback callback =
+ new ServiceBackupCallback(
+ mBackupManagerService.getBackupManagerBinder(), token);
// Start backup and wait for BackupManagerService to get callback for success or timeout
agent.doBackup(
- mSavedState, mBackupData, mNewState, Long.MAX_VALUE, token,
- mBackupManagerService.getBackupManagerBinder(), /*transportFlags=*/ 0);
+ mSavedState,
+ mBackupData,
+ mNewState,
+ /* quotaBytes */ Long.MAX_VALUE,
+ callback,
+ /* transportFlags */ 0);
if (!mBackupManagerService.waitUntilOperationComplete(token)) {
Slog.e(TAG, "Key-value backup failed on package " + packageName);
return false;
diff --git a/services/backup/java/com/android/server/backup/internal/BackupHandler.java b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
index 69f08ae..66b6b37 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupHandler.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupHandler.java
@@ -38,7 +38,6 @@
import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
-import com.android.server.backup.transport.TransportClient;
import com.android.server.backup.TransportManager;
import com.android.server.backup.fullbackup.PerformAdbBackupTask;
import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
@@ -52,6 +51,7 @@
import com.android.server.backup.params.RestoreParams;
import com.android.server.backup.restore.PerformAdbRestoreTask;
import com.android.server.backup.restore.PerformUnifiedRestoreTask;
+import com.android.server.backup.transport.TransportClient;
import java.util.ArrayList;
import java.util.Collections;
@@ -150,17 +150,22 @@
if (queue.size() > 0) {
// Spin up a backup state sequence and set it running
try {
- String dirName = transport.transportDirName();
OnTaskFinishedListener listener =
caller ->
transportManager
.disposeOfTransportClient(transportClient, caller);
- PerformBackupTask pbt = new PerformBackupTask(
- backupManagerService, transportClient, dirName, queue,
- oldJournal, null, null, listener, Collections.emptyList(), false,
- false /* nonIncremental */);
- Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
- sendMessage(pbtMessage);
+ PerformBackupTask.start(
+ backupManagerService,
+ transportClient,
+ transport.transportDirName(),
+ queue,
+ oldJournal,
+ /* observer */ null,
+ /* monitor */ null,
+ listener,
+ Collections.emptyList(),
+ /* userInitiated */ false,
+ /* nonIncremental */ false);
} catch (Exception e) {
// unable to ask the transport its dir name -- transient failure, since
// the above check succeeded. Try again next time.
@@ -405,13 +410,18 @@
backupManagerService.setBackupRunning(true);
backupManagerService.getWakelock().acquire();
- PerformBackupTask pbt = new PerformBackupTask(
+ PerformBackupTask.start(
backupManagerService,
- params.transportClient, params.dirName,
- kvQueue, null, params.observer, params.monitor, params.listener,
- params.fullPackages, true, params.nonIncrementalBackup);
- Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
- sendMessage(pbtMessage);
+ params.transportClient,
+ params.dirName,
+ kvQueue,
+ /* dataChangedJournal */ null,
+ params.observer,
+ params.monitor,
+ params.listener,
+ params.fullPackages,
+ /* userInitiated */ true,
+ params.nonIncrementalBackup);
break;
}
diff --git a/services/backup/java/com/android/server/backup/internal/BackupState.java b/services/backup/java/com/android/server/backup/internal/BackupState.java
index 937b167..320b555 100644
--- a/services/backup/java/com/android/server/backup/internal/BackupState.java
+++ b/services/backup/java/com/android/server/backup/internal/BackupState.java
@@ -7,5 +7,6 @@
INITIAL,
BACKUP_PM,
RUNNING_QUEUE,
+ CANCELLED,
FINAL
}
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 551b80f..c5df82e 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -16,16 +16,11 @@
package com.android.server.backup.internal;
-import static com.android.server.backup.BackupManagerService.DEBUG;
import static com.android.server.backup.BackupManagerService.DEBUG_BACKUP_TRACE;
import static com.android.server.backup.BackupManagerService.KEY_WIDGET_STATE;
-import static com.android.server.backup.BackupManagerService.MORE_DEBUG;
import static com.android.server.backup.BackupManagerService.OP_PENDING;
import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP;
-import static com.android.server.backup.BackupManagerService.OP_TYPE_BACKUP_WAIT;
import static com.android.server.backup.BackupManagerService.PACKAGE_MANAGER_SENTINEL;
-import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_OPERATION_TIMEOUT;
-import static com.android.server.backup.internal.BackupHandler.MSG_BACKUP_RESTORE_STEP;
import android.annotation.Nullable;
import android.app.ApplicationThreadConstants;
@@ -36,14 +31,16 @@
import android.app.backup.BackupManager;
import android.app.backup.BackupManagerMonitor;
import android.app.backup.BackupTransport;
+import android.app.backup.IBackupCallback;
+import android.app.backup.IBackupManager;
import android.app.backup.IBackupManagerMonitor;
import android.app.backup.IBackupObserver;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.os.Message;
+import android.os.ConditionVariable;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RemoteException;
import android.os.SELinux;
import android.os.UserHandle;
@@ -51,23 +48,24 @@
import android.system.ErrnoException;
import android.system.Os;
import android.util.EventLog;
+import android.util.Pair;
import android.util.Slog;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.backup.IBackupTransport;
import com.android.internal.util.Preconditions;
import com.android.server.AppWidgetBackupBridge;
import com.android.server.EventLogTags;
import com.android.server.backup.BackupAgentTimeoutParameters;
+import com.android.server.backup.BackupManagerService;
import com.android.server.backup.BackupRestoreTask;
import com.android.server.backup.DataChangedJournal;
import com.android.server.backup.KeyValueBackupJob;
-import com.android.server.backup.PackageManagerBackupAgent;
-import com.android.server.backup.BackupManagerService;
import com.android.server.backup.fullbackup.PerformFullTransportBackupTask;
+import com.android.server.backup.remote.RemoteCall;
+import com.android.server.backup.remote.RemoteCallable;
+import com.android.server.backup.remote.RemoteResult;
import com.android.server.backup.transport.TransportClient;
-import com.android.server.backup.transport.TransportUtils;
import com.android.server.backup.utils.AppBackupUtils;
import com.android.server.backup.utils.BackupManagerMonitorUtils;
import com.android.server.backup.utils.BackupObserverUtils;
@@ -85,85 +83,225 @@
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicInteger;
/**
- * This class handles the process of backing up a given list of key/value backup packages.
- * Also takes in a list of pending dolly backups and kicks them off when key/value backups
- * are done.
+ * Represents the task of performing a sequence of key-value backups for a given list of packages.
+ * Method {@link #run()} executes the backups to the transport specified via the {@code
+ * transportClient} parameter in the constructor.
*
- * Flow:
- * If required, backup @pm@.
- * For each pending key/value backup package:
- * - Bind to agent.
- * - Call agent.doBackup()
- * - Wait either for cancel/timeout or operationComplete() callback from the agent.
- * Start task to perform dolly backups.
+ * <p>A few definitions:
*
- * There are three entry points into this class:
- * - execute() [Called from the handler thread]
- * - operationComplete(long result) [Called from the handler thread]
- * - handleCancel(boolean cancelAll) [Can be called from any thread]
- * These methods synchronize on mCancelLock.
+ * <ul>
+ * <li>State directory: {@link BackupManagerService#getBaseStateDir()}/<transport>
+ * <li>State file: {@link
+ * BackupManagerService#getBaseStateDir()}/<transport>/<package><br>
+ * Represents the state of the backup data for a specific package in the current dataset.
+ * <li>Stage directory: {@link BackupManagerService#getDataDir()}
+ * <li>Stage file: {@link BackupManagerService#getDataDir()}/<package>.data<br>
+ * Contains staged data that the agents wrote via {@link BackupDataOutput}, to be transmitted
+ * to the transport.
+ * </ul>
*
- * Interaction with mCurrentOperations:
- * - An entry for this task is put into mCurrentOperations for the entire lifetime of the
- * task. This is useful to cancel the task if required.
- * - An ephemeral entry is put into mCurrentOperations each time we are waiting on for
- * response from a backup agent. This is used to plumb timeouts and completion callbacks.
+ * If there is no PackageManager (PM) pseudo-package state file in the state directory, the
+ * specified transport will be initialized with {@link IBackupTransport#initializeDevice()}.
+ *
+ * <p>The PM pseudo-package is the first package to be backed-up and sent to the transport in case
+ * of incremental choice. If non-incremental, PM will only be backed-up if specified in the queue,
+ * and if it's the case it will be re-positioned at the head of the queue.
+ *
+ * <p>Before starting, this task will register itself in {@link BackupManagerService} current
+ * operations.
+ *
+ * <p>In summary, this task will for each package:
+ *
+ * <ul>
+ * <li>Bind to its {@link IBackupAgent}.
+ * <li>Request transport quota and flags.
+ * <li>Call {@link IBackupAgent#doBackup(ParcelFileDescriptor, ParcelFileDescriptor,
+ * ParcelFileDescriptor, long, int, IBackupManager, int)} via {@link RemoteCall} passing the
+ * old state file descriptor (read), the backup data file descriptor (write), the new state
+ * file descriptor (write), the quota and the transport flags. This will call {@link
+ * BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)} with
+ * the old state file to be read, a {@link BackupDataOutput} object to write the backup data
+ * and the new state file to write. By writing to {@link BackupDataOutput}, the agent will
+ * write data to the stage file. The task will block waiting for either:
+ * <ul>
+ * <li>Agent response.
+ * <li>Agent time-out (specified via {@link
+ * BackupManagerService#getAgentTimeoutParameters()}.
+ * <li>External cancellation or thread interrupt.
+ * </ul>
+ * <li>Unbind the agent.
+ * <li>Assuming agent response, send the staged data that the agent wrote to disk to the transport
+ * via {@link IBackupTransport#performBackup(PackageInfo, ParcelFileDescriptor, int)}.
+ * <li>Call {@link IBackupTransport#finishBackup()} if previous call was successful.
+ * <li>Save the new state in the state file. During the agent call it was being written to
+ * <state file>.new, here we rename it and replace the old one.
+ * <li>Delete the stage file.
+ * </ul>
+ *
+ * In the end, this task will:
+ *
+ * <ul>
+ * <li>Mark data-changed for the remaining packages in the queue (skipped packages).
+ * <li>Delete the {@link DataChangedJournal} provided. Note that this should not be the current
+ * journal.
+ * <li>Set {@link BackupManagerService} current token as {@link
+ * IBackupTransport#getCurrentRestoreSet()}, if applicable.
+ * <li>Add the transport to the list of transports pending initialization ({@link
+ * BackupManagerService#getPendingInits()}) and kick-off initialization if the transport ever
+ * returned {@link BackupTransport#TRANSPORT_NOT_INITIALIZED}.
+ * <li>Unregister the task in current operations.
+ * <li>Release the wakelock.
+ * <li>Kick-off {@link PerformFullTransportBackupTask} if a list of full-backup packages was
+ * provided.
+ * </ul>
+ *
+ * The caller can specify whether this should be an incremental or non-incremental backup. In the
+ * case of non-incremental the agents will be passed an empty old state file, which signals that a
+ * complete backup should be performed.
+ *
+ * <p>This task is designed to run on a dedicated thread, with the exception of the {@link
+ * #handleCancel(boolean)} method, which can be called from any thread.
*/
-public class PerformBackupTask implements BackupRestoreTask {
+// TODO: Stop poking into BMS state and doing things for it (e.g. synchronizing on public locks)
+// TODO: Consider having the caller responsible for some clean-up (like resetting state)
+// TODO: Distinguish between cancel and time-out where possible for logging/monitoring/observing
+public class PerformBackupTask implements BackupRestoreTask, Runnable {
private static final String TAG = "PerformBackupTask";
+ private static final boolean DEBUG = BackupManagerService.DEBUG || true;
+ private static final boolean MORE_DEBUG = BackupManagerService.MORE_DEBUG || false;
+ private static final int THREAD_PRIORITY = Process.THREAD_PRIORITY_BACKGROUND;
+ private static final AtomicInteger THREAD_COUNT = new AtomicInteger();
private static final String BLANK_STATE_FILE_NAME = "blank_state";
@VisibleForTesting
public static final String STAGING_FILE_SUFFIX = ".data";
@VisibleForTesting
public static final String NEW_STATE_FILE_SUFFIX = ".new";
- private BackupManagerService backupManagerService;
- private final Object mCancelLock = new Object();
+ /**
+ * Creates a new {@link PerformBackupTask} for key-value backup operation, spins up a new
+ * dedicated thread and kicks off the operation in it.
+ *
+ * @param backupManagerService The {@link BackupManagerService} system service.
+ * @param transportClient The {@link TransportClient} that contains the transport used for the
+ * operation.
+ * @param transportDirName The value of {@link IBackupTransport#transportDirName()} for the
+ * transport whose {@link TransportClient} was provided above.
+ * @param queue The list of packages that will be backed-up, in the form of {@link
+ * BackupRequest}.
+ * @param dataChangedJournal The old data-changed journal file that will be deleted when the
+ * operation finishes (successfully or not) or {@code null}.
+ * @param observer A {@link IBackupObserver}.
+ * @param monitor A {@link IBackupManagerMonitor}.
+ * @param listener A {@link OnTaskFinishedListener} or {@code null}.
+ * @param pendingFullBackups The list of packages that will be passed for a new {@link
+ * PerformFullTransportBackupTask} operation, which will be started when this finishes.
+ * @param userInitiated Whether this was user-initiated or not.
+ * @param nonIncremental If {@code true}, this will be a complete backup for each package,
+ * otherwise it will be just an incremental one over the current dataset.
+ * @return The {@link PerformBackupTask} that was started.
+ */
+ public static PerformBackupTask start(
+ BackupManagerService backupManagerService,
+ TransportClient transportClient,
+ String transportDirName,
+ ArrayList<BackupRequest> queue,
+ @Nullable DataChangedJournal dataChangedJournal,
+ IBackupObserver observer,
+ IBackupManagerMonitor monitor,
+ @Nullable OnTaskFinishedListener listener,
+ List<String> pendingFullBackups,
+ boolean userInitiated,
+ boolean nonIncremental) {
+ PerformBackupTask task =
+ new PerformBackupTask(
+ backupManagerService,
+ transportClient,
+ transportDirName,
+ queue,
+ dataChangedJournal,
+ observer,
+ monitor,
+ listener,
+ pendingFullBackups,
+ userInitiated,
+ nonIncremental);
+ Thread thread = new Thread(task, "key-value-backup-" + THREAD_COUNT.incrementAndGet());
+ if (DEBUG) {
+ Slog.d(TAG, "Spinning thread " + thread.getName());
+ }
+ thread.start();
+ return task;
+ }
- private ArrayList<BackupRequest> mQueue;
- private ArrayList<BackupRequest> mOriginalQueue;
- private File mStateDir;
- @Nullable private DataChangedJournal mJournal;
- private BackupState mCurrentState;
- private List<String> mPendingFullBackups;
- private IBackupObserver mObserver;
- private IBackupManagerMonitor mMonitor;
-
+ private final BackupManagerService mBackupManagerService;
private final TransportClient mTransportClient;
+ private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
+ private final IBackupObserver mObserver;
private final OnTaskFinishedListener mListener;
- private final PerformFullTransportBackupTask mFullBackupTask;
+ private final boolean mUserInitiated;
+ private final boolean mNonIncremental;
private final int mCurrentOpToken;
- private volatile int mEphemeralOpToken;
+ private final File mStateDir;
+ private final ArrayList<BackupRequest> mOriginalQueue;
+ private final ArrayList<BackupRequest> mQueue;
+ private final List<String> mPendingFullBackups;
+ @Nullable private final DataChangedJournal mJournal;
+ private IBackupManagerMonitor mMonitor;
+ @Nullable private PerformFullTransportBackupTask mFullBackupTask;
- // carried information about the current in-flight operation
private IBackupAgent mAgentBinder;
private PackageInfo mCurrentPackage;
- private File mSavedStateName;
- private File mBackupDataName;
- private File mNewStateName;
+ private File mSavedStateFile;
+ private File mBackupDataFile;
+ private File mNewStateFile;
private ParcelFileDescriptor mSavedState;
private ParcelFileDescriptor mBackupData;
private ParcelFileDescriptor mNewState;
private int mStatus;
- private boolean mFinished;
- private final boolean mUserInitiated;
- private final boolean mNonIncremental;
- private final BackupAgentTimeoutParameters mAgentTimeoutParameters;
- private volatile boolean mCancelAll;
+ /**
+ * This {@link ConditionVariable} is used to signal that the cancel operation has been
+ * received by the task and that no more transport calls will be made. Anyone can call {@link
+ * ConditionVariable#block()} to wait for these conditions to hold true, but there should only
+ * be one place where {@link ConditionVariable#open()} is called. Also there should be no calls
+ * to {@link ConditionVariable#close()}, which means there is only one cancel per backup -
+ * subsequent calls to block will return immediately.
+ */
+ private final ConditionVariable mCancelAcknowledged = new ConditionVariable(false);
- public PerformBackupTask(BackupManagerService backupManagerService,
- TransportClient transportClient, String dirName,
- ArrayList<BackupRequest> queue, @Nullable DataChangedJournal journal,
- IBackupObserver observer, IBackupManagerMonitor monitor,
- @Nullable OnTaskFinishedListener listener, List<String> pendingFullBackups,
- boolean userInitiated, boolean nonIncremental) {
- this.backupManagerService = backupManagerService;
+ /**
+ * Set it to {@code true} and block on {@code mCancelAcknowledged} to wait for the cancellation.
+ * DO NOT set it to {@code false}.
+ */
+ private volatile boolean mCancelled = false;
+
+ /**
+ * If non-{@code null} there is a pending agent call being made. This call can be cancelled (and
+ * control returned to this task) with {@link RemoteCall#cancel()}.
+ */
+ @Nullable private volatile RemoteCall mPendingCall;
+
+ @VisibleForTesting
+ public PerformBackupTask(
+ BackupManagerService backupManagerService,
+ TransportClient transportClient,
+ String transportDirName,
+ ArrayList<BackupRequest> queue,
+ @Nullable DataChangedJournal journal,
+ IBackupObserver observer,
+ IBackupManagerMonitor monitor,
+ @Nullable OnTaskFinishedListener listener,
+ List<String> pendingFullBackups,
+ boolean userInitiated,
+ boolean nonIncremental) {
+ mBackupManagerService = backupManagerService;
mTransportClient = transportClient;
mOriginalQueue = queue;
- mQueue = new ArrayList<>();
+ // We need to retain the original queue contents in case of transport failure
+ mQueue = new ArrayList<>(mOriginalQueue);
mJournal = journal;
mObserver = observer;
mMonitor = monitor;
@@ -171,92 +309,80 @@
mPendingFullBackups = pendingFullBackups;
mUserInitiated = userInitiated;
mNonIncremental = nonIncremental;
- mAgentTimeoutParameters = Preconditions.checkNotNull(
- backupManagerService.getAgentTimeoutParameters(),
- "Timeout parameters cannot be null");
-
- mStateDir = new File(backupManagerService.getBaseStateDir(), dirName);
+ mAgentTimeoutParameters =
+ Preconditions.checkNotNull(
+ backupManagerService.getAgentTimeoutParameters(),
+ "Timeout parameters cannot be null");
+ mStateDir = new File(backupManagerService.getBaseStateDir(), transportDirName);
mCurrentOpToken = backupManagerService.generateRandomIntegerToken();
-
- mFinished = false;
-
- synchronized (backupManagerService.getCurrentOpLock()) {
- if (backupManagerService.isBackupOperationInProgress()) {
- if (DEBUG) {
- Slog.d(TAG, "Skipping backup since one is already in progress.");
- }
- mCancelAll = true;
- mFullBackupTask = null;
- mCurrentState = BackupState.FINAL;
- backupManagerService.addBackupTrace("Skipped. Backup already in progress.");
- } else {
- mCurrentState = BackupState.INITIAL;
- CountDownLatch latch = new CountDownLatch(1);
- String[] fullBackups =
- mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
- mFullBackupTask =
- new PerformFullTransportBackupTask(backupManagerService,
- transportClient,
- /*fullBackupRestoreObserver*/ null,
- fullBackups, /*updateSchedule*/ false, /*runningJob*/ null,
- latch,
- mObserver, mMonitor, mListener, mUserInitiated);
-
- registerTask();
- backupManagerService.addBackupTrace("STATE => INITIAL");
- }
- }
}
- /**
- * Put this task in the repository of running tasks.
- */
private void registerTask() {
- backupManagerService.putOperation(
+ mBackupManagerService.putOperation(
mCurrentOpToken, new Operation(OP_PENDING, this, OP_TYPE_BACKUP));
}
- /**
- * Remove this task from repository of running tasks.
- */
private void unregisterTask() {
- backupManagerService.removeOperation(mCurrentOpToken);
+ mBackupManagerService.removeOperation(mCurrentOpToken);
}
- // Main entry point: perform one chunk of work, updating the state as appropriate
- // and reposting the next chunk to the primary backup handler thread.
@Override
- @GuardedBy("mCancelLock")
- public void execute() {
- synchronized (mCancelLock) {
- switch (mCurrentState) {
- case INITIAL:
- beginBackup();
- break;
+ public void run() {
+ Process.setThreadPriority(THREAD_PRIORITY);
+ BackupState state = beginBackup();
+ while (state == BackupState.RUNNING_QUEUE || state == BackupState.BACKUP_PM) {
+ if (mCancelled) {
+ state = BackupState.CANCELLED;
+ }
+ switch (state) {
case BACKUP_PM:
- backupPm();
+ state = backupPm();
break;
-
case RUNNING_QUEUE:
- invokeNextAgent();
- break;
-
- case FINAL:
- if (!mFinished) {
- finalizeBackup();
- } else {
- Slog.e(TAG, "Duplicate finish of K/V pass");
+ Pair<BackupState, RemoteResult> stateAndResult = invokeNextAgent();
+ state = stateAndResult.first;
+ if (state == null) {
+ state = processAgentInvocation(stateAndResult.second);
}
break;
}
}
+ if (state == BackupState.CANCELLED) {
+ finalizeCancelledBackup();
+ } else {
+ finalizeBackup();
+ }
}
- // We're starting a backup pass. Initialize the transport if we haven't already.
- private void beginBackup() {
+ private BackupState processAgentInvocation(RemoteResult result) {
+ if (result == RemoteResult.FAILED_THREAD_INTERRUPTED) {
+ // Not an explicit cancel, we need to flag it
+ mCancelled = true;
+ handleAgentCancelled();
+ return BackupState.CANCELLED;
+ }
+ if (result == RemoteResult.FAILED_CANCELLED) {
+ handleAgentCancelled();
+ return BackupState.CANCELLED;
+ }
+ if (result == RemoteResult.FAILED_TIMED_OUT) {
+ handleAgentTimeout();
+ return BackupState.RUNNING_QUEUE;
+ }
+ Preconditions.checkState(result.succeeded());
+ return handleAgentResult(result.get());
+ }
+
+ @Override
+ public void execute() {}
+
+ @Override
+ public void operationComplete(long unusedResult) {}
+
+ private BackupState beginBackup() {
if (DEBUG_BACKUP_TRACE) {
- backupManagerService.clearBackupTrace();
+ mBackupManagerService.clearBackupTrace();
StringBuilder b = new StringBuilder(256);
b.append("beginBackup: [");
for (BackupRequest req : mOriginalQueue) {
@@ -264,8 +390,34 @@
b.append(req.packageName);
}
b.append(" ]");
- backupManagerService.addBackupTrace(b.toString());
+ mBackupManagerService.addBackupTrace(b.toString());
}
+ synchronized (mBackupManagerService.getCurrentOpLock()) {
+ if (mBackupManagerService.isBackupOperationInProgress()) {
+ if (DEBUG) {
+ Slog.d(TAG, "Skipping backup since one is already in progress.");
+ }
+ mBackupManagerService.addBackupTrace("Skipped. Backup already in progress.");
+ return BackupState.FINAL;
+ }
+ }
+
+ String[] fullBackups = mPendingFullBackups.toArray(new String[mPendingFullBackups.size()]);
+ mFullBackupTask =
+ new PerformFullTransportBackupTask(
+ mBackupManagerService,
+ mTransportClient,
+ /* fullBackupRestoreObserver */ null,
+ fullBackups,
+ /* updateSchedule */ false,
+ /* runningJob */ null,
+ new CountDownLatch(1),
+ mObserver,
+ mMonitor,
+ mListener,
+ mUserInitiated);
+ registerTask();
+ mBackupManagerService.addBackupTrace("STATE => INITIAL");
mAgentBinder = null;
mStatus = BackupTransport.TRANSPORT_OK;
@@ -273,16 +425,10 @@
// Sanity check: if the queue is empty we have no work to do.
if (mOriginalQueue.isEmpty() && mPendingFullBackups.isEmpty()) {
Slog.w(TAG, "Backup begun with an empty queue - nothing to do.");
- backupManagerService.addBackupTrace("queue empty at begin");
- executeNextState(BackupState.FINAL);
- return;
+ mBackupManagerService.addBackupTrace("queue empty at begin");
+ return BackupState.FINAL;
}
- // We need to retain the original queue contents in case of transport
- // failure, but we want a working copy that we can manipulate along
- // the way.
- mQueue = (ArrayList<BackupRequest>) mOriginalQueue.clone();
-
// When the transport is forcing non-incremental key/value payloads, we send the
// metadata only if it explicitly asks for it.
boolean skipPm = mNonIncremental;
@@ -292,8 +438,7 @@
// we performed a backup. Drop it from the working queue now that
// we're committed to evaluating it for backup regardless.
for (int i = 0; i < mQueue.size(); i++) {
- if (PACKAGE_MANAGER_SENTINEL.equals(
- mQueue.get(i).packageName)) {
+ if (PACKAGE_MANAGER_SENTINEL.equals(mQueue.get(i).packageName)) {
if (MORE_DEBUG) {
Slog.i(TAG, "Metadata in queue; eliding");
}
@@ -309,17 +454,17 @@
File pmState = new File(mStateDir, PACKAGE_MANAGER_SENTINEL);
try {
IBackupTransport transport = mTransportClient.connectOrThrow("PBT.beginBackup()");
- final String transportName = transport.transportDirName();
+ String transportName = transport.name();
EventLog.writeEvent(EventLogTags.BACKUP_START, transportName);
// If we haven't stored package manager metadata yet, we must init the transport.
- if (mStatus == BackupTransport.TRANSPORT_OK && pmState.length() <= 0) {
+ if (pmState.length() <= 0) {
Slog.i(TAG, "Initializing (wiping) backup state and transport storage");
- backupManagerService.addBackupTrace("initializing transport " + transportName);
- backupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ mBackupManagerService.addBackupTrace("initializing transport " + transportName);
+ mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
mStatus = transport.initializeDevice();
- backupManagerService.addBackupTrace("transport.initializeDevice() == " + mStatus);
+ mBackupManagerService.addBackupTrace("transport.initializeDevice() == " + mStatus);
if (mStatus == BackupTransport.TRANSPORT_OK) {
EventLog.writeEvent(EventLogTags.BACKUP_INITIALIZE);
} else {
@@ -327,82 +472,81 @@
Slog.e(TAG, "Transport error in initializeDevice()");
}
}
-
- if (skipPm) {
- Slog.d(TAG, "Skipping backup of package metadata.");
- executeNextState(BackupState.RUNNING_QUEUE);
- } else {
- // As the package manager is running here in the system process we can just set up
- // its agent directly. Thus we always run this pass because it's cheap and this way
- // we guarantee that we don't get out of step even if we're selecting among various
- // transports at run time.
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- executeNextState(BackupState.BACKUP_PM);
- }
- }
} catch (Exception e) {
Slog.e(TAG, "Error in backup thread during init", e);
- backupManagerService.addBackupTrace("Exception in backup thread during init: " + e);
+ mBackupManagerService.addBackupTrace("Exception in backup thread during init: " + e);
mStatus = BackupTransport.TRANSPORT_ERROR;
- } finally {
- // If we've succeeded so far, we will move to the BACKUP_PM state. If something has gone
- // wrong then that won't have happen so cleanup.
- backupManagerService.addBackupTrace("exiting prelim: " + mStatus);
- if (mStatus != BackupTransport.TRANSPORT_OK) {
- // if things went wrong at this point, we need to
- // restage everything and try again later.
- backupManagerService.resetBackupState(mStateDir); // Just to make sure.
- // In case of any other error, it's backup transport error.
- executeNextState(BackupState.FINAL);
- }
}
+ mBackupManagerService.addBackupTrace("exiting prelim: " + mStatus);
+
+ if (mStatus != BackupTransport.TRANSPORT_OK) {
+ // if things went wrong at this point, we need to
+ // restage everything and try again later.
+ mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ return BackupState.FINAL;
+ }
+
+ if (skipPm) {
+ Slog.d(TAG, "Skipping backup of package metadata.");
+ return BackupState.RUNNING_QUEUE;
+ }
+
+ return BackupState.BACKUP_PM;
}
- private void backupPm() {
+ private BackupState backupPm() {
+ RemoteResult agentResult = null;
+ BackupState nextState;
try {
// The package manager doesn't have a proper <application> etc, but since it's running
// here in the system process we can just set up its agent directly and use a synthetic
// BackupRequest.
- BackupAgent pmAgent = backupManagerService.makeMetadataAgent();
- mStatus = invokeAgentForBackup(
- PACKAGE_MANAGER_SENTINEL,
- IBackupAgent.Stub.asInterface(pmAgent.onBind()));
- backupManagerService.addBackupTrace("PMBA invoke: " + mStatus);
+ BackupAgent pmAgent = mBackupManagerService.makeMetadataAgent();
+ Pair<Integer, RemoteResult> statusAndResult =
+ invokeAgentForBackup(
+ PACKAGE_MANAGER_SENTINEL,
+ IBackupAgent.Stub.asInterface(pmAgent.onBind()));
+ mStatus = statusAndResult.first;
+ agentResult = statusAndResult.second;
- // Because the PMBA is a local instance, it has already executed its backup callback and
- // returned. Blow away the lingering (spurious) pending timeout message for it.
- backupManagerService.getBackupHandler().removeMessages(
- MSG_BACKUP_OPERATION_TIMEOUT);
+ mBackupManagerService.addBackupTrace("PMBA invoke: " + mStatus);
} catch (Exception e) {
Slog.e(TAG, "Error in backup thread during pm", e);
- backupManagerService.addBackupTrace("Exception in backup thread during pm: " + e);
+ mBackupManagerService.addBackupTrace("Exception in backup thread during pm: " + e);
mStatus = BackupTransport.TRANSPORT_ERROR;
- } finally {
- // If we've succeeded so far, invokeAgentForBackup() will have run the PM
- // metadata and its completion/timeout callback will continue the state
- // machine chain. If it failed that won't happen; we handle that now.
- backupManagerService.addBackupTrace("exiting backupPm: " + mStatus);
- if (mStatus != BackupTransport.TRANSPORT_OK) {
- // if things went wrong at this point, we need to
- // restage everything and try again later.
- backupManagerService.resetBackupState(mStateDir); // Just to make sure.
- executeNextState(BackupState.FINAL);
- }
}
+ mBackupManagerService.addBackupTrace("exiting backupPm: " + mStatus);
+
+ if (mStatus == BackupTransport.TRANSPORT_OK) {
+ Preconditions.checkNotNull(agentResult);
+ nextState = processAgentInvocation(agentResult);
+ } else {
+ // if things went wrong at this point, we need to
+ // restage everything and try again later.
+ mBackupManagerService.resetBackupState(mStateDir); // Just to make sure.
+ nextState = BackupState.FINAL;
+ }
+
+ return nextState;
}
- // Transport has been initialized and the PM metadata submitted successfully
- // if that was warranted. Now we process the single next thing in the queue.
- private void invokeNextAgent() {
+ /**
+ * Returns either:
+ *
+ * <ul>
+ * <li>(next state, {@code null}): In case we failed to call the agent.
+ * <li>({@code null}, agent result): In case we successfully called the agent.
+ * </ul>
+ */
+ private Pair<BackupState, RemoteResult> invokeNextAgent() {
mStatus = BackupTransport.TRANSPORT_OK;
- backupManagerService.addBackupTrace("invoke q=" + mQueue.size());
+ mBackupManagerService.addBackupTrace("invoke q=" + mQueue.size());
// Sanity check that we have work to do. If not, skip to the end where
// we reestablish the wakelock invariants etc.
if (mQueue.isEmpty()) {
if (MORE_DEBUG) Slog.i(TAG, "queue now empty");
- executeNextState(BackupState.FINAL);
- return;
+ return Pair.create(BackupState.FINAL, null);
}
// pop the entry we're going to process on this step
@@ -410,15 +554,16 @@
mQueue.remove(0);
Slog.d(TAG, "starting key/value backup of " + request);
- backupManagerService.addBackupTrace("launch agent for " + request.packageName);
+ mBackupManagerService.addBackupTrace("launch agent for " + request.packageName);
// Verify that the requested app exists; it might be something that
// requested a backup but was then uninstalled. The request was
// journalled and rather than tamper with the journal it's safer
// to sanity-check here. This also gives us the classname of the
// package's backup agent.
+ RemoteResult agentResult = null;
try {
- PackageManager pm = backupManagerService.getPackageManager();
+ PackageManager pm = mBackupManagerService.getPackageManager();
mCurrentPackage = pm.getPackageInfo(request.packageName,
PackageManager.GET_SIGNING_CERTIFICATES);
if (!AppBackupUtils.appIsEligibleForBackup(mCurrentPackage.applicationInfo, pm)) {
@@ -427,14 +572,13 @@
// backups.
Slog.i(TAG, "Package " + request.packageName
+ " no longer supports backup; skipping");
- backupManagerService.addBackupTrace("skipping - not eligible, completion is noop");
+ mBackupManagerService.addBackupTrace("skipping - not eligible, completion is noop");
// Shouldn't happen in case of requested backup, as pre-check was done in
// #requestBackup(), except to app update done concurrently
BackupObserverUtils.sendBackupOnPackageResult(mObserver,
mCurrentPackage.packageName,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
- executeNextState(BackupState.RUNNING_QUEUE);
- return;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
}
if (AppBackupUtils.appGetsFullBackup(mCurrentPackage)) {
@@ -443,42 +587,41 @@
// Don't proceed with a key/value backup for it in this case.
Slog.i(TAG, "Package " + request.packageName
+ " requests full-data rather than key/value; skipping");
- backupManagerService.addBackupTrace(
+ mBackupManagerService.addBackupTrace(
"skipping - fullBackupOnly, completion is noop");
// Shouldn't happen in case of requested backup, as pre-check was done in
// #requestBackup()
BackupObserverUtils.sendBackupOnPackageResult(mObserver,
mCurrentPackage.packageName,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
- executeNextState(BackupState.RUNNING_QUEUE);
- return;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
}
if (AppBackupUtils.appIsStopped(mCurrentPackage.applicationInfo)) {
// The app has been force-stopped or cleared or just installed,
// and not yet launched out of that state, so just as it won't
// receive broadcasts, we won't run it for backup.
- backupManagerService.addBackupTrace("skipping - stopped");
+ mBackupManagerService.addBackupTrace("skipping - stopped");
BackupObserverUtils.sendBackupOnPackageResult(mObserver,
mCurrentPackage.packageName,
BackupManager.ERROR_BACKUP_NOT_ALLOWED);
- executeNextState(BackupState.RUNNING_QUEUE);
- return;
+ return Pair.create(BackupState.RUNNING_QUEUE, null);
}
- IBackupAgent agent = null;
try {
- backupManagerService.setWorkSource(
+ mBackupManagerService.setWorkSource(
new WorkSource(mCurrentPackage.applicationInfo.uid));
- agent = backupManagerService.bindToAgentSynchronous(mCurrentPackage.applicationInfo,
- ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
- backupManagerService.addBackupTrace("agent bound; a? = " + (agent != null));
+ IBackupAgent agent =
+ mBackupManagerService.bindToAgentSynchronous(
+ mCurrentPackage.applicationInfo,
+ ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL);
+ mBackupManagerService.addBackupTrace("agent bound; a? = " + (agent != null));
if (agent != null) {
mAgentBinder = agent;
- mStatus = invokeAgentForBackup(request.packageName, agent);
- // at this point we'll either get a completion callback from the
- // agent, or a timeout message on the main handler. either way, we're
- // done here as long as we're successful so far.
+ Pair<Integer, RemoteResult> statusAndResult =
+ invokeAgentForBackup(request.packageName, agent);
+ mStatus = statusAndResult.first;
+ agentResult = statusAndResult.second;
} else {
// Timeout waiting for the agent
mStatus = BackupTransport.AGENT_ERROR;
@@ -487,62 +630,59 @@
// Try for the next one.
Slog.d(TAG, "error in bind/backup", ex);
mStatus = BackupTransport.AGENT_ERROR;
- backupManagerService.addBackupTrace("agent SE");
+ mBackupManagerService.addBackupTrace("agent SE");
}
- } catch (NameNotFoundException e) {
+ } catch (PackageManager.NameNotFoundException e) {
Slog.d(TAG, "Package does not exist; skipping");
- backupManagerService.addBackupTrace("no such package");
+ mBackupManagerService.addBackupTrace("no such package");
mStatus = BackupTransport.AGENT_UNKNOWN;
} finally {
- backupManagerService.setWorkSource(null);
-
- // If there was an agent error, no timeout/completion handling will occur.
- // That means we need to direct to the next state ourselves.
- if (mStatus != BackupTransport.TRANSPORT_OK) {
- BackupState nextState = BackupState.RUNNING_QUEUE;
- mAgentBinder = null;
-
- // An agent-level failure means we reenqueue this one agent for
- // a later retry, but otherwise proceed normally.
- if (mStatus == BackupTransport.AGENT_ERROR) {
- if (MORE_DEBUG) {
- Slog.i(TAG, "Agent failure for " + request.packageName
- + " - restaging");
- }
- backupManagerService.dataChangedImpl(request.packageName);
- mStatus = BackupTransport.TRANSPORT_OK;
- if (mQueue.isEmpty()) nextState = BackupState.FINAL;
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
- BackupManager.ERROR_AGENT_FAILURE);
- } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
- // Failed lookup of the app, so we couldn't bring up an agent, but
- // we're otherwise fine. Just drop it and go on to the next as usual.
- mStatus = BackupTransport.TRANSPORT_OK;
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, request.packageName,
- BackupManager.ERROR_PACKAGE_NOT_FOUND);
- } else {
- // Transport-level failure means we reenqueue everything
- revertAndEndBackup();
- nextState = BackupState.FINAL;
- }
-
- executeNextState(nextState);
- } else {
- // success case
- backupManagerService.addBackupTrace("expecting completion/timeout callback");
- }
+ mBackupManagerService.setWorkSource(null);
}
+
+ if (mStatus != BackupTransport.TRANSPORT_OK) {
+ BackupState nextState = BackupState.RUNNING_QUEUE;
+ mAgentBinder = null;
+
+ // An agent-level failure means we re-enqueue this one agent for
+ // a later retry, but otherwise proceed normally.
+ if (mStatus == BackupTransport.AGENT_ERROR) {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Agent failure for " + request.packageName + " - restaging");
+ }
+ mBackupManagerService.dataChangedImpl(request.packageName);
+ mStatus = BackupTransport.TRANSPORT_OK;
+ BackupObserverUtils
+ .sendBackupOnPackageResult(mObserver, mCurrentPackage.packageName,
+ BackupManager.ERROR_AGENT_FAILURE);
+ } else if (mStatus == BackupTransport.AGENT_UNKNOWN) {
+ // Failed lookup of the app, so we couldn't bring up an agent, but
+ // we're otherwise fine. Just drop it and go on to the next as usual.
+ mStatus = BackupTransport.TRANSPORT_OK;
+ BackupObserverUtils
+ .sendBackupOnPackageResult(mObserver, request.packageName,
+ BackupManager.ERROR_PACKAGE_NOT_FOUND);
+ } else {
+ // Transport-level failure means we re-enqueue everything
+ revertAndEndBackup();
+ nextState = BackupState.FINAL;
+ }
+
+ return Pair.create(nextState, null);
+ }
+
+ // Success: caller will figure out the state based on call result
+ mBackupManagerService.addBackupTrace("call made; result = " + agentResult);
+ return Pair.create(null, agentResult);
}
private void finalizeBackup() {
- backupManagerService.addBackupTrace("finishing");
+ mBackupManagerService.addBackupTrace("finishing");
// Mark packages that we didn't backup (because backup was cancelled, etc.) as needing
// backup.
for (BackupRequest req : mQueue) {
- backupManagerService.dataChangedImpl(req.packageName);
+ mBackupManagerService.dataChangedImpl(req.packageName);
}
// Either backup was successful, in which case we of course do not need
@@ -557,65 +697,62 @@
// done a backup, we can now record what the current backup dataset token
// is.
String callerLogString = "PBT.finalizeBackup()";
- if ((backupManagerService.getCurrentToken() == 0) && (mStatus
+ if ((mBackupManagerService.getCurrentToken() == 0) && (mStatus
== BackupTransport.TRANSPORT_OK)) {
- backupManagerService.addBackupTrace("success; recording token");
+ mBackupManagerService.addBackupTrace("success; recording token");
try {
- IBackupTransport transport =
- mTransportClient.connectOrThrow(callerLogString);
- backupManagerService.setCurrentToken(transport.getCurrentRestoreSet());
- backupManagerService.writeRestoreTokens();
+ IBackupTransport transport = mTransportClient.connectOrThrow(callerLogString);
+ mBackupManagerService.setCurrentToken(transport.getCurrentRestoreSet());
+ mBackupManagerService.writeRestoreTokens();
} catch (Exception e) {
// nothing for it at this point, unfortunately, but this will be
// recorded the next time we fully succeed.
Slog.e(TAG, "Transport threw reporting restore set: " + e.getMessage());
- backupManagerService.addBackupTrace("transport threw returning token");
+ mBackupManagerService.addBackupTrace("transport threw returning token");
}
}
// Set up the next backup pass - at this point we can set mBackupRunning
- // to false to allow another pass to fire, because we're done with the
- // state machine sequence and the wakelock is refcounted.
- synchronized (backupManagerService.getQueueLock()) {
- backupManagerService.setBackupRunning(false);
+ // to false to allow another pass to fire
+ synchronized (mBackupManagerService.getQueueLock()) {
+ mBackupManagerService.setBackupRunning(false);
if (mStatus == BackupTransport.TRANSPORT_NOT_INITIALIZED) {
// Make sure we back up everything and perform the one-time init
if (MORE_DEBUG) {
Slog.d(TAG, "Server requires init; rerunning");
}
- backupManagerService.addBackupTrace("init required; rerunning");
+ mBackupManagerService.addBackupTrace("init required; rerunning");
try {
- String name = backupManagerService.getTransportManager()
+ String name = mBackupManagerService.getTransportManager()
.getTransportName(mTransportClient.getTransportComponent());
- backupManagerService.getPendingInits().add(name);
+ mBackupManagerService.getPendingInits().add(name);
} catch (Exception e) {
Slog.w(TAG, "Failed to query transport name for init: " + e.getMessage());
// swallow it and proceed; we don't rely on this
}
clearMetadata();
- backupManagerService.backupNow();
+ mBackupManagerService.backupNow();
}
}
- backupManagerService.clearBackupTrace();
+ mBackupManagerService.clearBackupTrace();
unregisterTask();
- if (!mCancelAll && mStatus == BackupTransport.TRANSPORT_OK &&
+ if (!mCancelled && mStatus == BackupTransport.TRANSPORT_OK &&
mPendingFullBackups != null && !mPendingFullBackups.isEmpty()) {
Slog.d(TAG, "Starting full backups for: " + mPendingFullBackups);
// Acquiring wakelock for PerformFullTransportBackupTask before its start.
- backupManagerService.getWakelock().acquire();
+ mBackupManagerService.getWakelock().acquire();
// The full-backup task is now responsible for calling onFinish() on mListener, which
// was the listener we passed it.
(new Thread(mFullBackupTask, "full-transport-requested")).start();
- } else if (mCancelAll) {
+ } else if (mCancelled) {
mListener.onFinished(callerLogString);
if (mFullBackupTask != null) {
mFullBackupTask.unregisterTask();
}
- BackupObserverUtils.sendBackupFinished(mObserver,
- BackupManager.ERROR_BACKUP_CANCELLED);
+ BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.ERROR_BACKUP_CANCELLED);
} else {
mListener.onFinished(callerLogString);
mFullBackupTask.unregisterTask();
@@ -623,8 +760,7 @@
case BackupTransport.TRANSPORT_OK:
case BackupTransport.TRANSPORT_QUOTA_EXCEEDED:
case BackupTransport.TRANSPORT_PACKAGE_REJECTED:
- BackupObserverUtils.sendBackupFinished(mObserver,
- BackupManager.SUCCESS);
+ BackupObserverUtils.sendBackupFinished(mObserver, BackupManager.SUCCESS);
break;
case BackupTransport.TRANSPORT_NOT_INITIALIZED:
BackupObserverUtils.sendBackupFinished(mObserver,
@@ -637,10 +773,9 @@
break;
}
}
- mFinished = true;
Slog.i(TAG, "K/V backup pass finished.");
// Only once we're entirely finished do we release the wakelock for k/v backup.
- backupManagerService.getWakelock().release();
+ mBackupManagerService.getWakelock().release();
}
// Remove the PM metadata state. This will generate an init on the next pass.
@@ -649,27 +784,34 @@
if (pmState.exists()) pmState.delete();
}
- // Invoke an agent's doBackup() and start a timeout message spinning on the main
- // handler in case it doesn't get back to us.
- private int invokeAgentForBackup(String packageName, IBackupAgent agent) {
+ /**
+ * Returns a {@link Pair}. The first of the pair contains the status. In case the status is
+ * {@link BackupTransport#TRANSPORT_OK}, the second of the pair contains the agent result,
+ * otherwise {@code null}.
+ */
+ private Pair<Integer, RemoteResult> invokeAgentForBackup(
+ String packageName, IBackupAgent agent) {
if (DEBUG) {
Slog.d(TAG, "invokeAgentForBackup on " + packageName);
}
- backupManagerService.addBackupTrace("invoking " + packageName);
+ mBackupManagerService.addBackupTrace("invoking " + packageName);
- File blankStateName = new File(mStateDir, BLANK_STATE_FILE_NAME);
- mSavedStateName = new File(mStateDir, packageName);
- mBackupDataName =
- new File(backupManagerService.getDataDir(), packageName + STAGING_FILE_SUFFIX);
- mNewStateName = new File(mStateDir, packageName + NEW_STATE_FILE_SUFFIX);
- if (MORE_DEBUG) Slog.d(TAG, "data file: " + mBackupDataName);
+ File blankStateFile = new File(mStateDir, BLANK_STATE_FILE_NAME);
+ mSavedStateFile = new File(mStateDir, packageName);
+ mBackupDataFile =
+ new File(mBackupManagerService.getDataDir(), packageName + STAGING_FILE_SUFFIX);
+ mNewStateFile = new File(mStateDir, packageName + NEW_STATE_FILE_SUFFIX);
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "data file: " + mBackupDataFile);
+ }
+
mSavedState = null;
mBackupData = null;
mNewState = null;
boolean callingAgent = false;
- mEphemeralOpToken = backupManagerService.generateRandomIntegerToken();
+ final RemoteResult agentResult;
try {
// Look up the package info & signatures. This is first so that if it
// throws an exception, there's no file setup yet that would need to
@@ -681,24 +823,21 @@
mCurrentPackage.packageName = packageName;
}
- // In a full backup, we pass a null ParcelFileDescriptor as
- // the saved-state "file". For key/value backups we pass the old state if
- // an incremental backup is required, and a blank state otherwise.
mSavedState = ParcelFileDescriptor.open(
- mNonIncremental ? blankStateName : mSavedStateName,
+ (mNonIncremental) ? blankStateFile : mSavedStateFile,
ParcelFileDescriptor.MODE_READ_ONLY |
ParcelFileDescriptor.MODE_CREATE); // Make an empty file if necessary
- mBackupData = ParcelFileDescriptor.open(mBackupDataName,
+ mBackupData = ParcelFileDescriptor.open(mBackupDataFile,
ParcelFileDescriptor.MODE_READ_WRITE |
ParcelFileDescriptor.MODE_CREATE |
ParcelFileDescriptor.MODE_TRUNCATE);
- if (!SELinux.restorecon(mBackupDataName)) {
- Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataName);
+ if (!SELinux.restorecon(mBackupDataFile)) {
+ Slog.e(TAG, "SELinux restorecon failed on " + mBackupDataFile);
}
- mNewState = ParcelFileDescriptor.open(mNewStateName,
+ mNewState = ParcelFileDescriptor.open(mNewStateFile,
ParcelFileDescriptor.MODE_READ_WRITE |
ParcelFileDescriptor.MODE_CREATE |
ParcelFileDescriptor.MODE_TRUNCATE);
@@ -710,36 +849,36 @@
callingAgent = true;
// Initiate the target's backup pass
- backupManagerService.addBackupTrace("setting timeout");
long kvBackupAgentTimeoutMillis =
mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis();
- backupManagerService.prepareOperationTimeout(
- mEphemeralOpToken, kvBackupAgentTimeoutMillis, this, OP_TYPE_BACKUP_WAIT);
- backupManagerService.addBackupTrace("calling agent doBackup()");
+ mBackupManagerService.addBackupTrace("calling agent doBackup()");
- agent.doBackup(
- mSavedState, mBackupData, mNewState, quota, mEphemeralOpToken,
- backupManagerService.getBackupManagerBinder(), transport.getTransportFlags());
+ agentResult =
+ remoteCall(
+ callback ->
+ agent.doBackup(
+ mSavedState,
+ mBackupData,
+ mNewState,
+ quota,
+ callback,
+ transport.getTransportFlags()),
+ kvBackupAgentTimeoutMillis);
} catch (Exception e) {
Slog.e(TAG, "Error invoking for backup on " + packageName + ". " + e);
- backupManagerService.addBackupTrace("exception: " + e);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName,
- e.toString());
+ mBackupManagerService.addBackupTrace("exception: " + e);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName, e.toString());
errorCleanup();
- return callingAgent ? BackupTransport.AGENT_ERROR
- : BackupTransport.TRANSPORT_ERROR;
+ int status =
+ callingAgent ? BackupTransport.AGENT_ERROR : BackupTransport.TRANSPORT_ERROR;
+ return Pair.create(status, null);
} finally {
if (mNonIncremental) {
- blankStateName.delete();
+ blankStateFile.delete();
}
}
- // At this point the agent is off and running. The next thing to happen will
- // either be a callback from the agent, at which point we'll process its data
- // for transport, or a timeout. Either way the next phase will happen in
- // response to the TimeoutHandler interface callbacks.
- backupManagerService.addBackupTrace("invoke success");
- return BackupTransport.TRANSPORT_OK;
+ return Pair.create(BackupTransport.TRANSPORT_OK, agentResult);
}
private void failAgent(IBackupAgent agent, String message) {
@@ -829,327 +968,319 @@
}
}
- @Override
- @GuardedBy("mCancelLock")
- public void operationComplete(long unusedResult) {
- backupManagerService.removeOperation(mEphemeralOpToken);
- synchronized (mCancelLock) {
- // The agent reported back to us!
- if (mFinished) {
- Slog.d(TAG, "operationComplete received after task finished.");
- return;
- }
+ private BackupState handleAgentResult(long unusedResult) {
+ Preconditions.checkState(mBackupData != null);
- if (mBackupData == null) {
- // This callback was racing with our timeout, so we've cleaned up the
- // agent state already and are on to the next thing. We have nothing
- // further to do here: agent state having been cleared means that we've
- // initiated the appropriate next operation.
- final String pkg = (mCurrentPackage != null)
- ? mCurrentPackage.packageName : "[none]";
- if (MORE_DEBUG) {
- Slog.i(TAG, "Callback after agent teardown: " + pkg);
- }
- backupManagerService.addBackupTrace("late opComplete; curPkg = " + pkg);
- return;
- }
-
- final String pkgName = mCurrentPackage.packageName;
- final long filepos = mBackupDataName.length();
- FileDescriptor fd = mBackupData.getFileDescriptor();
- try {
- // If it's a 3rd party app, see whether they wrote any protected keys
- // and complain mightily if they are attempting shenanigans.
- if (mCurrentPackage.applicationInfo != null &&
- (mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
- == 0) {
- ParcelFileDescriptor readFd = ParcelFileDescriptor.open(mBackupDataName,
- ParcelFileDescriptor.MODE_READ_ONLY);
- BackupDataInput in = new BackupDataInput(readFd.getFileDescriptor());
- try {
- while (in.readNextHeader()) {
- final String key = in.getKey();
- if (key != null && key.charAt(0) >= 0xff00) {
- // Not okay: crash them and bail.
- failAgent(mAgentBinder, "Illegal backup key: " + key);
- backupManagerService
- .addBackupTrace("illegal key " + key + " from " + pkgName);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
- "bad key");
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
- mCurrentPackage,
- BackupManagerMonitor
- .LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
- BackupManagerMonitorUtils.putMonitoringExtra(null,
- BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY,
- key));
- backupManagerService.getBackupHandler().removeMessages(
- MSG_BACKUP_OPERATION_TIMEOUT);
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_AGENT_FAILURE);
- errorCleanup();
- if (MORE_DEBUG) {
- Slog.i(TAG, "Agent failure for " + pkgName
- + " with illegal key: " + key + "; dropped");
- }
- executeNextState(mQueue.isEmpty() ? BackupState.FINAL
- : BackupState.RUNNING_QUEUE);
- return;
+ final String pkgName = mCurrentPackage.packageName;
+ final long filepos = mBackupDataFile.length();
+ FileDescriptor fd = mBackupData.getFileDescriptor();
+ try {
+ // If it's a 3rd party app, see whether they wrote any protected keys
+ // and complain mightily if they are attempting shenanigans.
+ if (mCurrentPackage.applicationInfo != null &&
+ (mCurrentPackage.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
+ == 0) {
+ ParcelFileDescriptor readFd = ParcelFileDescriptor.open(mBackupDataFile,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ BackupDataInput in = new BackupDataInput(readFd.getFileDescriptor());
+ try {
+ while (in.readNextHeader()) {
+ final String key = in.getKey();
+ if (key != null && key.charAt(0) >= 0xff00) {
+ // Not okay: crash them and bail.
+ failAgent(mAgentBinder, "Illegal backup key: " + key);
+ mBackupManagerService
+ .addBackupTrace("illegal key " + key + " from " + pkgName);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, pkgName,
+ "bad key");
+ mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_ILLEGAL_KEY,
+ mCurrentPackage,
+ BackupManagerMonitor
+ .LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+ BackupManagerMonitorUtils.putMonitoringExtra(null,
+ BackupManagerMonitor.EXTRA_LOG_ILLEGAL_KEY,
+ key));
+ BackupObserverUtils
+ .sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_AGENT_FAILURE);
+ errorCleanup();
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Agent failure for " + pkgName
+ + " with illegal key: " + key + "; dropped");
}
- in.skipEntityData();
+
+ return BackupState.RUNNING_QUEUE;
}
- } finally {
- if (readFd != null) {
- readFd.close();
- }
+ in.skipEntityData();
+ }
+ } finally {
+ if (readFd != null) {
+ readFd.close();
}
}
-
- // Piggyback the widget state payload, if any
- writeWidgetPayloadIfAppropriate(fd, pkgName);
- } catch (IOException e) {
- // Hard disk error; recovery/failure policy TBD. For now roll back,
- // but we may want to consider this a transport-level failure (i.e.
- // we're in such a bad state that we can't contemplate doing backup
- // operations any more during this pass).
- Slog.w(TAG, "Unable to save widget state for " + pkgName);
- try {
- Os.ftruncate(fd, filepos);
- } catch (ErrnoException ee) {
- Slog.w(TAG, "Unable to roll back!");
- }
}
- // Spin the data off to the transport and proceed with the next stage.
- if (MORE_DEBUG) {
- Slog.v(TAG, "operationComplete(): sending data to transport for "
- + pkgName);
- }
- backupManagerService.getBackupHandler().removeMessages(MSG_BACKUP_OPERATION_TIMEOUT);
- clearAgentState();
- backupManagerService.addBackupTrace("operation complete");
-
- IBackupTransport transport = mTransportClient.connect("PBT.operationComplete()");
- ParcelFileDescriptor backupData = null;
- mStatus = BackupTransport.TRANSPORT_OK;
- long size = 0;
+ // Piggyback the widget state payload, if any
+ writeWidgetPayloadIfAppropriate(fd, pkgName);
+ } catch (IOException e) {
+ // Hard disk error; recovery/failure policy TBD. For now roll back,
+ // but we may want to consider this a transport-level failure (i.e.
+ // we're in such a bad state that we can't contemplate doing backup
+ // operations any more during this pass).
+ Slog.w(TAG, "Unable read backup data or to save widget state for " + pkgName);
try {
- TransportUtils.checkTransportNotNull(transport);
- size = mBackupDataName.length();
- if (size > 0) {
- boolean isNonIncremental = mSavedStateName.length() == 0;
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- backupData = ParcelFileDescriptor.open(mBackupDataName,
- ParcelFileDescriptor.MODE_READ_ONLY);
- backupManagerService.addBackupTrace("sending data to transport");
+ Os.ftruncate(fd, filepos);
+ } catch (ErrnoException ee) {
+ Slog.w(TAG, "Unable to roll back!");
+ }
+ }
- int userInitiatedFlag =
- mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
- int incrementalFlag =
- isNonIncremental
+ clearAgentState();
+ mBackupManagerService.addBackupTrace("operation complete");
+
+ ParcelFileDescriptor backupData = null;
+ mStatus = BackupTransport.TRANSPORT_OK;
+ long size = 0;
+ try {
+ IBackupTransport transport = mTransportClient.connectOrThrow("PBT.handleAgentResult()");
+ size = mBackupDataFile.length();
+ if (size > 0) {
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Sending non-empty data to transport for " + pkgName);
+ }
+ boolean isNonIncremental = mSavedStateFile.length() == 0;
+ if (mStatus == BackupTransport.TRANSPORT_OK) {
+ backupData = ParcelFileDescriptor.open(mBackupDataFile,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ mBackupManagerService.addBackupTrace("sending data to transport");
+
+ int userInitiatedFlag =
+ mUserInitiated ? BackupTransport.FLAG_USER_INITIATED : 0;
+ int incrementalFlag =
+ isNonIncremental
? BackupTransport.FLAG_NON_INCREMENTAL
: BackupTransport.FLAG_INCREMENTAL;
- int flags = userInitiatedFlag | incrementalFlag;
+ int flags = userInitiatedFlag | incrementalFlag;
- mStatus = transport.performBackup(mCurrentPackage, backupData, flags);
- }
+ mStatus = transport.performBackup(mCurrentPackage, backupData, flags);
+ }
- if (isNonIncremental
+ if (isNonIncremental
&& mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- // TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED is only valid if the backup was
- // incremental, as if the backup is non-incremental there is no state to
- // clear. This avoids us ending up in a retry loop if the transport always
- // returns this code.
- Slog.w(TAG,
- "Transport requested non-incremental but already the case, error");
- backupManagerService.addBackupTrace(
- "Transport requested non-incremental but already the case, error");
- mStatus = BackupTransport.TRANSPORT_ERROR;
- }
-
- // TODO - We call finishBackup() for each application backed up, because
- // we need to know now whether it succeeded or failed. Instead, we should
- // hold off on finishBackup() until the end, which implies holding off on
- // renaming *all* the output state files (see below) until that happens.
-
- backupManagerService.addBackupTrace("data delivered: " + mStatus);
- if (mStatus == BackupTransport.TRANSPORT_OK) {
- backupManagerService.addBackupTrace("finishing op on transport");
- mStatus = transport.finishBackup();
- backupManagerService.addBackupTrace("finished: " + mStatus);
- } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- backupManagerService.addBackupTrace("transport rejected package");
- }
- } else {
- if (MORE_DEBUG) {
- Slog.i(TAG, "no backup data written; not calling transport");
- }
- backupManagerService.addBackupTrace("no data to send");
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
- null);
+ // TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED is only valid if the backup was
+ // incremental, as if the backup is non-incremental there is no state to
+ // clear. This avoids us ending up in a retry loop if the transport always
+ // returns this code.
+ Slog.w(TAG, "Transport requested non-incremental but already the case, error");
+ mBackupManagerService.addBackupTrace(
+ "Transport requested non-incremental but already the case, error");
+ mStatus = BackupTransport.TRANSPORT_ERROR;
}
+ mBackupManagerService.addBackupTrace("data delivered: " + mStatus);
if (mStatus == BackupTransport.TRANSPORT_OK) {
- // After successful transport, delete the now-stale data
- // and juggle the files so that next time we supply the agent
- // with the new state file it just created.
- mBackupDataName.delete();
- mNewStateName.renameTo(mSavedStateName);
- BackupObserverUtils
- .sendBackupOnPackageResult(mObserver, pkgName, BackupManager.SUCCESS);
- EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
- backupManagerService.logBackupComplete(pkgName);
+ mBackupManagerService.addBackupTrace("finishing op on transport");
+ mStatus = transport.finishBackup();
+ mBackupManagerService.addBackupTrace("finished: " + mStatus);
} else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- // The transport has rejected backup of this specific package. Roll it
- // back but proceed with running the rest of the queue.
- mBackupDataName.delete();
- mNewStateName.delete();
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
- EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
- } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
- EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
-
- } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- Slog.i(TAG, "Transport lost data, retrying package");
- backupManagerService.addBackupTrace(
- "Transport lost data, retrying package:" + pkgName);
- BackupManagerMonitorUtils.monitorEvent(
- mMonitor,
- BackupManagerMonitor
- .LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED,
- mCurrentPackage,
- BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
- /*extras=*/ null);
-
- mBackupDataName.delete();
- mSavedStateName.delete();
- mNewStateName.delete();
-
- // Immediately retry the package by adding it back to the front of the queue.
- // We cannot add @pm@ to the queue because we back it up separately at the start
- // of the backup pass in state BACKUP_PM. Instead we retry this state (see
- // below).
- if (!PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
- mQueue.add(0, new BackupRequest(pkgName));
- }
-
- } else {
- // Actual transport-level failure to communicate the data to the backend
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ mBackupManagerService.addBackupTrace("transport rejected package");
}
- } catch (Exception e) {
- BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
- BackupManager.ERROR_TRANSPORT_ABORTED);
- Slog.e(TAG, "Transport error backing up " + pkgName, e);
- EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
- mStatus = BackupTransport.TRANSPORT_ERROR;
- } finally {
- try {
- if (backupData != null) backupData.close();
- } catch (IOException e) {
+ } else {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "No backup data written; not calling transport");
}
+ mBackupManagerService.addBackupTrace("no data to send");
+ mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_NO_DATA_TO_SEND,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_BACKUP_MANAGER_POLICY,
+ null);
}
- final BackupState nextState;
- if (mStatus == BackupTransport.TRANSPORT_OK
- || mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
- // Success or single-package rejection. Proceed with the next app if any,
- // otherwise we're done.
- nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
+ if (mStatus == BackupTransport.TRANSPORT_OK) {
+ // After successful transport, delete the now-stale data
+ // and juggle the files so that next time we supply the agent
+ // with the new state file it just created.
+ mBackupDataFile.delete();
+ mNewStateFile.renameTo(mSavedStateFile);
+ BackupObserverUtils.sendBackupOnPackageResult(
+ mObserver, pkgName, BackupManager.SUCCESS);
+ EventLog.writeEvent(EventLogTags.BACKUP_PACKAGE, pkgName, size);
+ mBackupManagerService.logBackupComplete(pkgName);
+ } else if (mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+ // The transport has rejected backup of this specific package. Roll it
+ // back but proceed with running the rest of the queue.
+ mBackupDataFile.delete();
+ mNewStateFile.delete();
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
+ EventLogTags.writeBackupAgentFailure(pkgName, "Transport rejected");
+ } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
+ EventLog.writeEvent(EventLogTags.BACKUP_QUOTA_EXCEEDED, pkgName);
} else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
- // We want to immediately retry the current package.
- if (PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
- nextState = BackupState.BACKUP_PM;
- } else {
- // This is an ordinary package so we will have added it back into the queue
- // above. Thus, we proceed processing the queue.
- nextState = BackupState.RUNNING_QUEUE;
+ Slog.i(TAG, "Transport lost data, retrying package");
+ mBackupManagerService.addBackupTrace(
+ "Transport lost data, retrying package:" + pkgName);
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_TRANSPORT,
+ /*extras=*/ null);
+
+ mBackupDataFile.delete();
+ mSavedStateFile.delete();
+ mNewStateFile.delete();
+
+ // Immediately retry the package by adding it back to the front of the queue.
+ // We cannot add @pm@ to the queue because we back it up separately at the start
+ // of the backup pass in state BACKUP_PM. Instead we retry this state (see
+ // below).
+ if (!PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
+ mQueue.add(0, new BackupRequest(pkgName));
}
- } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
- if (MORE_DEBUG) {
- Slog.d(TAG, "Package " + mCurrentPackage.packageName +
- " hit quota limit on k/v backup");
- }
- if (mAgentBinder != null) {
- try {
- TransportUtils.checkTransportNotNull(transport);
- long quota = transport.getBackupQuota(mCurrentPackage.packageName, false);
- mAgentBinder.doQuotaExceeded(size, quota);
- } catch (Exception e) {
- Slog.e(TAG, "Unable to notify about quota exceeded: " + e.getMessage());
- }
- }
- nextState = (mQueue.isEmpty()) ? BackupState.FINAL : BackupState.RUNNING_QUEUE;
} else {
- // Any other error here indicates a transport-level failure. That means
- // we need to halt everything and reschedule everything for next time.
- revertAndEndBackup();
- nextState = BackupState.FINAL;
+ // Actual transport-level failure to communicate the data to the backend
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_ABORTED);
+ EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ }
+ } catch (Exception e) {
+ BackupObserverUtils.sendBackupOnPackageResult(mObserver, pkgName,
+ BackupManager.ERROR_TRANSPORT_ABORTED);
+ Slog.e(TAG, "Transport error backing up " + pkgName, e);
+ EventLog.writeEvent(EventLogTags.BACKUP_TRANSPORT_FAILURE, pkgName);
+ mStatus = BackupTransport.TRANSPORT_ERROR;
+ } finally {
+ try {
+ if (backupData != null) {
+ backupData.close();
+ }
+ } catch (IOException e) {
+ Slog.w(TAG, "Error closing backup data fd");
+ }
+ }
+
+ final BackupState nextState;
+ if (mStatus == BackupTransport.TRANSPORT_OK
+ || mStatus == BackupTransport.TRANSPORT_PACKAGE_REJECTED) {
+ // Success or single-package rejection. Proceed with the next app if any,
+ // otherwise we're done.
+ nextState = BackupState.RUNNING_QUEUE;
+
+ } else if (mStatus == BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED) {
+ // We want to immediately retry the current package.
+ if (PACKAGE_MANAGER_SENTINEL.equals(pkgName)) {
+ nextState = BackupState.BACKUP_PM;
+ } else {
+ // This is an ordinary package so we will have added it back into the queue
+ // above. Thus, we proceed processing the queue.
+ nextState = BackupState.RUNNING_QUEUE;
}
- executeNextState(nextState);
+ } else if (mStatus == BackupTransport.TRANSPORT_QUOTA_EXCEEDED) {
+ if (MORE_DEBUG) {
+ Slog.d(TAG, "Package " + mCurrentPackage.packageName +
+ " hit quota limit on k/v backup");
+ }
+ if (mAgentBinder != null) {
+ try {
+ IBackupTransport transport =
+ mTransportClient.connectOrThrow("PBT.handleAgentResult()");
+ long quota = transport.getBackupQuota(mCurrentPackage.packageName, false);
+ mAgentBinder.doQuotaExceeded(size, quota);
+ } catch (Exception e) {
+ Slog.e(TAG, "Unable to notify about quota exceeded: " + e.getMessage());
+ }
+ }
+ nextState = BackupState.RUNNING_QUEUE;
+ } else {
+ // Any other error here indicates a transport-level failure. That means
+ // we need to halt everything and reschedule everything for next time.
+ revertAndEndBackup();
+ nextState = BackupState.FINAL;
}
+
+ return nextState;
}
-
+ /**
+ * Cancels this task. After this method returns there will be no more calls to the transport.
+ *
+ * <p>If this method is executed while an agent is performing a backup, we will stop waiting for
+ * it, disregard its backup data and finalize the task. However, if this method is executed in
+ * between agent calls, the backup data of the last called agent will be sent to
+ * the transport and we will not consider the next agent (nor the rest of the queue), proceeding
+ * to finalize the backup.
+ *
+ * @param cancelAll MUST be {@code true}. Will be removed.
+ */
@Override
- @GuardedBy("mCancelLock")
public void handleCancel(boolean cancelAll) {
- backupManagerService.removeOperation(mEphemeralOpToken);
- synchronized (mCancelLock) {
- if (mFinished) {
- // We have already cancelled this operation.
- if (MORE_DEBUG) {
- Slog.d(TAG, "Ignoring stale cancel. cancelAll=" + cancelAll);
- }
- return;
- }
- mCancelAll = cancelAll;
- final String logPackageName = (mCurrentPackage != null)
- ? mCurrentPackage.packageName
- : "no_package_yet";
- Slog.i(TAG, "Cancel backing up " + logPackageName);
- EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, logPackageName);
- backupManagerService.addBackupTrace(
- "cancel of " + logPackageName + ", cancelAll=" + cancelAll);
- mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor,
- BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
- mCurrentPackage, BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
- BackupManagerMonitorUtils.putMonitoringExtra(null,
- BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL,
- mCancelAll));
- errorCleanup();
- if (!cancelAll) {
- // The current agent either timed out or was cancelled running doBackup().
- // Restage it for the next time we run a backup pass.
- // !!! TODO: keep track of failure counts per agent, and blacklist those which
- // fail repeatedly (i.e. have proved themselves to be buggy).
- executeNextState(
- mQueue.isEmpty() ? BackupState.FINAL : BackupState.RUNNING_QUEUE);
- backupManagerService.dataChangedImpl(mCurrentPackage.packageName);
- } else {
- finalizeBackup();
- }
+ Preconditions.checkArgument(cancelAll, "Can't partially cancel a key-value backup task");
+ if (MORE_DEBUG) {
+ Slog.v(TAG, "Cancel received");
}
+ mCancelled = true;
+ RemoteCall pendingCall = mPendingCall;
+ if (pendingCall != null) {
+ pendingCall.cancel();
+ }
+ mCancelAcknowledged.block();
+ }
+
+ private void handleAgentTimeout() {
+ String packageName = getPackageNameForLog();
+ Slog.i(TAG, "Agent " + packageName + " timed out");
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+ mBackupManagerService.addBackupTrace("timeout of " + packageName);
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+ BackupManagerMonitorUtils.putMonitoringExtra(
+ null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, false));
+ errorCleanup();
+ }
+
+ private void handleAgentCancelled() {
+ String packageName = getPackageNameForLog();
+ Slog.i(TAG, "Cancel backing up " + packageName);
+ EventLog.writeEvent(EventLogTags.BACKUP_AGENT_FAILURE, packageName);
+ mBackupManagerService.addBackupTrace("cancel of " + packageName);
+ errorCleanup();
+ }
+
+ private void finalizeCancelledBackup() {
+ mMonitor =
+ BackupManagerMonitorUtils.monitorEvent(
+ mMonitor,
+ BackupManagerMonitor.LOG_EVENT_ID_KEY_VALUE_BACKUP_CANCEL,
+ mCurrentPackage,
+ BackupManagerMonitor.LOG_EVENT_CATEGORY_AGENT,
+ BackupManagerMonitorUtils.putMonitoringExtra(
+ null, BackupManagerMonitor.EXTRA_LOG_CANCEL_ALL, true));
+ finalizeBackup();
+ // finalizeBackup() may call the transport, so we only acknowledge the cancellation here.
+ mCancelAcknowledged.open();
+ }
+
+ private String getPackageNameForLog() {
+ return (mCurrentPackage != null) ? mCurrentPackage.packageName : "no_package_yet";
}
private void revertAndEndBackup() {
if (MORE_DEBUG) {
Slog.i(TAG, "Reverting backup queue - restaging everything");
}
- backupManagerService.addBackupTrace("transport error; reverting");
+ mBackupManagerService.addBackupTrace("transport error; reverting");
// We want to reset the backup schedule based on whatever the transport suggests
// by way of retry/backoff time.
@@ -1162,59 +1293,65 @@
Slog.w(TAG, "Unable to contact transport for recommended backoff: " + e.getMessage());
delay = 0; // use the scheduler's default
}
- KeyValueBackupJob.schedule(backupManagerService.getContext(), delay,
- backupManagerService.getConstants());
+ KeyValueBackupJob.schedule(mBackupManagerService.getContext(), delay,
+ mBackupManagerService.getConstants());
for (BackupRequest request : mOriginalQueue) {
- backupManagerService.dataChangedImpl(request.packageName);
+ mBackupManagerService.dataChangedImpl(request.packageName);
}
-
}
private void errorCleanup() {
- mBackupDataName.delete();
- mNewStateName.delete();
+ mBackupDataFile.delete();
+ mNewStateFile.delete();
clearAgentState();
}
// Cleanup common to both success and failure cases
private void clearAgentState() {
try {
- if (mSavedState != null) mSavedState.close();
+ if (mSavedState != null) {
+ mSavedState.close();
+ }
} catch (IOException e) {
+ Slog.w(TAG, "Error closing old state fd");
}
try {
- if (mBackupData != null) mBackupData.close();
+ if (mBackupData != null) {
+ mBackupData.close();
+ }
} catch (IOException e) {
+ Slog.w(TAG, "Error closing backup data fd");
}
try {
- if (mNewState != null) mNewState.close();
+ if (mNewState != null) {
+ mNewState.close();
+ }
} catch (IOException e) {
+ Slog.w(TAG, "Error closing new state fd");
}
- synchronized (backupManagerService.getCurrentOpLock()) {
+ synchronized (mBackupManagerService.getCurrentOpLock()) {
// Current-operation callback handling requires the validity of these various
// bits of internal state as an invariant of the operation still being live.
// This means we make sure to clear all of the state in unison inside the lock.
- backupManagerService.getCurrentOperations().remove(mEphemeralOpToken);
mSavedState = mBackupData = mNewState = null;
}
- // If this was a pseudopackage there's no associated Activity Manager state
+ // If this was a pseudo-package there's no associated Activity Manager state
if (mCurrentPackage.applicationInfo != null) {
- backupManagerService.addBackupTrace("unbinding " + mCurrentPackage.packageName);
- backupManagerService.unbindAgent(mCurrentPackage.applicationInfo);
+ mBackupManagerService.addBackupTrace("unbinding " + mCurrentPackage.packageName);
+ mBackupManagerService.unbindAgent(mCurrentPackage.applicationInfo);
}
}
- private void executeNextState(BackupState nextState) {
+ private RemoteResult remoteCall(RemoteCallable<IBackupCallback> remoteCallable, long timeoutMs)
+ throws RemoteException {
+ mPendingCall = new RemoteCall(mCancelled, remoteCallable, timeoutMs);
+ RemoteResult result = mPendingCall.call();
if (MORE_DEBUG) {
- Slog.i(TAG, " => executing next step on "
- + this + " nextState=" + nextState);
+ Slog.v(TAG, "Agent call returned " + result);
}
- backupManagerService.addBackupTrace("executeNextState => " + nextState);
- mCurrentState = nextState;
- Message msg = backupManagerService.getBackupHandler().obtainMessage(
- MSG_BACKUP_RESTORE_STEP, this);
- backupManagerService.getBackupHandler().sendMessage(msg);
+ mPendingCall = null;
+ return result;
}
}
diff --git a/services/backup/java/com/android/server/backup/remote/FutureBackupCallback.java b/services/backup/java/com/android/server/backup/remote/FutureBackupCallback.java
new file mode 100644
index 0000000..1445cc3
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/FutureBackupCallback.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import android.app.backup.IBackupCallback;
+import android.os.RemoteException;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * An implementation of {@link IBackupCallback} that completes the {@link CompletableFuture}
+ * provided in the constructor with a successful {@link RemoteResult}.
+ */
+public class FutureBackupCallback extends IBackupCallback.Stub {
+ private final CompletableFuture<RemoteResult> mFuture;
+
+ FutureBackupCallback(CompletableFuture<RemoteResult> future) {
+ mFuture = future;
+ }
+
+ @Override
+ public void operationComplete(long result) throws RemoteException {
+ mFuture.complete(RemoteResult.successful(result));
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/remote/RemoteCall.java b/services/backup/java/com/android/server/backup/remote/RemoteCall.java
new file mode 100644
index 0000000..ac84811
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/RemoteCall.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import android.annotation.WorkerThread;
+import android.app.backup.IBackupCallback;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * A wrapper that encapsulates an outbound call from the system process, converting an asynchronous
+ * operation into a synchronous operation with time-out and cancellation built-in. This was built to
+ * be able to call one-way binder methods that accept a {@link IBackupCallback} as a callback and
+ * handle the result inline.
+ *
+ * <p>Create one {@link RemoteCall} object providing the actual call in the form of a {@link
+ * RemoteCallable} that accepts a {@link IBackupCallback}. Perform the call by calling {@link
+ * #call()}, at which point {@link RemoteCall} will execute the callable providing an implementation
+ * of the callback that communicates the result back to this object. Even if the call returns
+ * straight away (which is the case for one-way methods) the method will only return when either the
+ * callback is called, time-out happens, or someone calls {@link #cancel()}.
+ *
+ * <p>This class was designed to have the method {@link #call()} called only once.
+ */
+// TODO: Kick-off callable in dedicated thread (because of local calls, which are synchronous)
+public class RemoteCall {
+ private final RemoteCallable<IBackupCallback> mCallable;
+ private final CompletableFuture<RemoteResult> mFuture;
+ private final long mTimeoutMs;
+
+ /**
+ * Creates a new {@link RemoteCall} object for a given callable.
+ *
+ * @param callable A function that signals its completion by calling {@link
+ * IBackupCallback#operationComplete(long)} on the object provided as a parameter.
+ * @param timeoutMs The time in milliseconds after which {@link #call()} will return with {@link
+ * RemoteResult#FAILED_TIMED_OUT} if the callable hasn't completed and no one canceled. The
+ * time starts to be counted in {@link #call()}.
+ */
+ public RemoteCall(RemoteCallable<IBackupCallback> callable, long timeoutMs) {
+ this(false, callable, timeoutMs);
+ }
+
+ /**
+ * Same as {@link #RemoteCall(RemoteCallable, long)} but with parameter {@code cancelled}.
+ *
+ * @param cancelled Whether the call has already been canceled. It has the same effect of
+ * calling {@link #cancel()} before {@link #call()}.
+ * @see #RemoteCall(RemoteCallable, long)
+ */
+ public RemoteCall(boolean cancelled, RemoteCallable<IBackupCallback> callable, long timeoutMs) {
+ mCallable = callable;
+ mTimeoutMs = timeoutMs;
+ mFuture = new CompletableFuture<>();
+ if (cancelled) {
+ cancel();
+ }
+ }
+
+ /**
+ * Kicks-off the callable provided in the constructor and blocks before returning, waiting for
+ * the first of these to happen:
+ *
+ * <ul>
+ * <li>The callback passed to {@link RemoteCallable} is called with the result. We return a
+ * successful {@link RemoteResult} with the result.
+ * <li>Time-out happens. We return {@link RemoteResult#FAILED_TIMED_OUT}.
+ * <li>Someone calls {@link #cancel()} on this object. We return {@link
+ * RemoteResult#FAILED_CANCELLED}.
+ * </ul>
+ *
+ * <p>This method can't be called from the main thread and was designed to be called only once.
+ *
+ * @return A {@link RemoteResult} with the result of the operation.
+ * @throws RemoteException If the callable throws it.
+ */
+ @WorkerThread
+ public RemoteResult call() throws RemoteException {
+ // If called on the main-thread we would never get a time-out != 0
+ Preconditions.checkState(
+ !Looper.getMainLooper().isCurrentThread(), "Can't call call() on main thread");
+
+ if (!mFuture.isDone()) {
+ if (mTimeoutMs == 0L) {
+ timeOut();
+ } else {
+ Handler.getMain().postDelayed(this::timeOut, mTimeoutMs);
+ mCallable.call(new FutureBackupCallback(mFuture));
+ }
+ }
+ try {
+ return mFuture.get();
+ } catch (InterruptedException e) {
+ return RemoteResult.FAILED_THREAD_INTERRUPTED;
+ } catch (ExecutionException e) {
+ throw new IllegalStateException("Future unexpectedly completed with an exception");
+ }
+ }
+
+ /**
+ * Attempts to cancel the operation. It will only be successful if executed before the callback
+ * is called and before the time-out.
+ *
+ * <p>This method can be called from any thread, any time, including the same thread that called
+ * {@link #call()} (which is obviously only possible if the former is called before the latter).
+ */
+ public void cancel() {
+ mFuture.complete(RemoteResult.FAILED_CANCELLED);
+ }
+
+ private void timeOut() {
+ mFuture.complete(RemoteResult.FAILED_TIMED_OUT);
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/remote/RemoteCallable.java b/services/backup/java/com/android/server/backup/remote/RemoteCallable.java
new file mode 100644
index 0000000..d2671ff
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/RemoteCallable.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import android.os.RemoteException;
+
+/**
+ * Implementations should perform a remote call in {@link #call(Object)}, possibly throwing {@link
+ * RemoteException}.
+ */
+@FunctionalInterface
+public interface RemoteCallable<T> {
+ void call(T input) throws RemoteException;
+}
diff --git a/services/backup/java/com/android/server/backup/remote/RemoteResult.java b/services/backup/java/com/android/server/backup/remote/RemoteResult.java
new file mode 100644
index 0000000..7f4f469
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/RemoteResult.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import android.annotation.IntDef;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Represents the result of a {@link RemoteCall}. It can be either {@link #FAILED_TIMED_OUT}, {@link
+ * #FAILED_CANCELLED}, {@link #FAILED_THREAD_INTERRUPTED} or a successful result, in which case
+ * {@link #get()} returns its value.
+ *
+ * <p>Use {@link #succeeded()} to check for successful result, or direct identity comparison to
+ * check for specific failures, like {@code result == RemoteResult.FAILED_CANCELLED}.
+ */
+public class RemoteResult {
+ public static final RemoteResult FAILED_TIMED_OUT = new RemoteResult(Type.FAILED_TIMED_OUT, 0);
+ public static final RemoteResult FAILED_CANCELLED = new RemoteResult(Type.FAILED_CANCELLED, 0);
+ public static final RemoteResult FAILED_THREAD_INTERRUPTED =
+ new RemoteResult(Type.FAILED_THREAD_INTERRUPTED, 0);
+
+ public static RemoteResult successful(long value) {
+ return new RemoteResult(Type.SUCCESS, value);
+ }
+
+ @Type private final int mType;
+ private final long mValue;
+
+ private RemoteResult(@Type int type, long value) {
+ mType = type;
+ mValue = value;
+ }
+
+ public boolean succeeded() {
+ return mType == Type.SUCCESS;
+ }
+
+ /**
+ * Returns the value of this result.
+ *
+ * @throws IllegalStateException in case this is not a successful result.
+ */
+ public long get() {
+ Preconditions.checkState(succeeded(), "Can't obtain value of failed result");
+ return mValue;
+ }
+
+ @Override
+ public String toString() {
+ return "RemoteResult{" + toStringDescription() + "}";
+ }
+
+ private String toStringDescription() {
+ switch (mType) {
+ case Type.SUCCESS:
+ return Long.toString(mValue);
+ case Type.FAILED_TIMED_OUT:
+ return "FAILED_TIMED_OUT";
+ case Type.FAILED_CANCELLED:
+ return "FAILED_CANCELLED";
+ case Type.FAILED_THREAD_INTERRUPTED:
+ return "FAILED_THREAD_INTERRUPTED";
+ }
+ throw new AssertionError("Unknown type");
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof RemoteResult)) {
+ return false;
+ }
+ RemoteResult that = (RemoteResult) o;
+ return mType == that.mType && mValue == that.mValue;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mType, mValue);
+ }
+
+ @IntDef({
+ Type.SUCCESS,
+ Type.FAILED_TIMED_OUT,
+ Type.FAILED_CANCELLED,
+ Type.FAILED_THREAD_INTERRUPTED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ private @interface Type {
+ int SUCCESS = 0;
+ int FAILED_TIMED_OUT = 1;
+ int FAILED_CANCELLED = 2;
+ int FAILED_THREAD_INTERRUPTED = 3;
+ }
+}
diff --git a/services/backup/java/com/android/server/backup/remote/ServiceBackupCallback.java b/services/backup/java/com/android/server/backup/remote/ServiceBackupCallback.java
new file mode 100644
index 0000000..28d85a6
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/remote/ServiceBackupCallback.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import android.app.backup.IBackupCallback;
+import android.app.backup.IBackupManager;
+import android.os.RemoteException;
+
+import com.android.server.backup.BackupManagerService;
+
+/**
+ * An implementation of {@link IBackupCallback} that routes the result to {@link
+ * BackupManagerService} via {@link IBackupManager#opComplete(int, long)} passing the token provided
+ * in the constructor.
+ */
+public class ServiceBackupCallback extends IBackupCallback.Stub {
+ private final IBackupManager mBackupManager;
+ private final int mToken;
+
+ public ServiceBackupCallback(IBackupManager backupManager, int token) {
+ mBackupManager = backupManager;
+ mToken = token;
+ }
+
+ @Override
+ public void operationComplete(long result) throws RemoteException {
+ mBackupManager.opComplete(mToken, result);
+ }
+}
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index c63b8f4..9a7c345 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -34,7 +34,6 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.BinderInternal;
-import com.android.server.LocalServices;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -131,6 +130,7 @@
public static class LifeCycle extends SystemService {
private BinderCallsStatsService mService;
+ private BinderCallsStats mBinderCallsStats;
public LifeCycle(Context context) {
super(context);
@@ -138,9 +138,9 @@
@Override
public void onStart() {
- BinderCallsStats binderCallsStats = new BinderCallsStats(new Random());
- mService = new BinderCallsStatsService(binderCallsStats);
- LocalServices.addService(Internal.class, new Internal(binderCallsStats));
+ mBinderCallsStats = new BinderCallsStats(new BinderCallsStats.Injector());
+ mService = new BinderCallsStatsService(mBinderCallsStats);
+ publishLocalService(Internal.class, new Internal(mBinderCallsStats));
publishBinderService("binder_calls_stats", mService);
boolean detailedTrackingEnabled = SystemProperties.getBoolean(
PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, false);
@@ -149,7 +149,7 @@
Slog.i(TAG, "Enabled CPU usage tracking for binder calls. Controlled by "
+ PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING
+ " or via dumpsys binder_calls_stats --enable-detailed-tracking");
- binderCallsStats.setDetailedTracking(true);
+ mBinderCallsStats.setDetailedTracking(true);
}
}
@@ -157,6 +157,7 @@
public void onBootPhase(int phase) {
if (SystemService.PHASE_SYSTEM_SERVICES_READY == phase) {
mService.systemReady(getContext());
+ mBinderCallsStats.systemReady(getContext());
}
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 2054e0a..6b3f8f8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -500,6 +500,9 @@
private final IpConnectivityLog mMetricsLog;
+ @GuardedBy("mBandwidthRequests")
+ private final SparseArray<Integer> mBandwidthRequests = new SparseArray(10);
+
@VisibleForTesting
final MultinetworkPolicyTracker mMultinetworkPolicyTracker;
@@ -2107,6 +2110,18 @@
pw.println("currently holding WakeLock for: " + (duration / 1000) + "s");
}
mWakelockLogs.reverseDump(fd, pw, args);
+
+ pw.println();
+ pw.println("bandwidth update requests (by uid):");
+ pw.increaseIndent();
+ synchronized (mBandwidthRequests) {
+ for (int i = 0; i < mBandwidthRequests.size(); i++) {
+ pw.println("[" + mBandwidthRequests.keyAt(i)
+ + "]: " + mBandwidthRequests.valueAt(i));
+ }
+ }
+ pw.decreaseIndent();
+
pw.decreaseIndent();
}
}
@@ -4267,6 +4282,14 @@
}
if (nai != null) {
nai.asyncChannel.sendMessage(android.net.NetworkAgent.CMD_REQUEST_BANDWIDTH_UPDATE);
+ synchronized (mBandwidthRequests) {
+ final int uid = Binder.getCallingUid();
+ Integer uidReqs = mBandwidthRequests.get(uid);
+ if (uidReqs == null) {
+ uidReqs = new Integer(0);
+ }
+ mBandwidthRequests.put(uid, ++uidReqs);
+ }
return true;
}
return false;
@@ -5863,4 +5886,4 @@
pw.println(" Get airplane mode.");
}
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index fd74613..784dfb4 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -51,6 +51,7 @@
import org.xmlpull.v1.XmlSerializer;
import android.Manifest;
+import android.accessibilityservice.AccessibilityService;
import android.annotation.AnyThread;
import android.annotation.BinderThread;
import android.annotation.ColorInt;
@@ -888,10 +889,12 @@
if (showImeUri.equals(uri)) {
updateKeyboardFromSettingsLocked();
} else if (accessibilityRequestingNoImeUri.equals(uri)) {
- mAccessibilityRequestingNoSoftKeyboard = Settings.Secure.getIntForUser(
+ final int accessibilitySoftKeyboardSetting = Settings.Secure.getIntForUser(
mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
- 0, mUserId) == 1;
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, 0, mUserId);
+ mAccessibilityRequestingNoSoftKeyboard =
+ (accessibilitySoftKeyboardSetting & AccessibilityService.SHOW_MODE_MASK)
+ == AccessibilityService.SHOW_MODE_HIDDEN;
if (mAccessibilityRequestingNoSoftKeyboard) {
final boolean showRequested = mShowRequested;
hideCurrentInputLocked(0, null);
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 9631e46..abcd6ef 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -1495,10 +1495,9 @@
}
try {
- mConnector.execute("idletimer", "add", iface, Integer.toString(timeout),
- Integer.toString(type));
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type));
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type));
@@ -1529,10 +1528,10 @@
}
try {
- mConnector.execute("idletimer", "remove", iface,
- Integer.toString(params.timeout), Integer.toString(params.type));
- } catch (NativeDaemonConnectorException e) {
- throw e.rethrowAsParcelableException();
+ mNetdService.idletimerRemoveInterface(iface,
+ params.timeout, Integer.toString(params.type));
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new IllegalStateException(e);
}
mActiveIdleTimers.remove(iface);
mDaemonHandler.post(new Runnable() {
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 92005d2..6409bb3 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -47,8 +47,10 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.ProviderInfo;
import android.content.pm.UserInfo;
import android.content.res.Configuration;
@@ -81,6 +83,7 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.os.UserManagerInternal;
import android.os.storage.DiskInfo;
import android.os.storage.IObbActionListener;
import android.os.storage.IStorageEventListener;
@@ -97,11 +100,13 @@
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.DataUnit;
import android.util.Log;
import android.util.Pair;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.TimeUtils;
import android.util.Xml;
@@ -174,7 +179,12 @@
/* Read during boot to decide whether to enable zram when available */
private static final String ZRAM_ENABLED_PROPERTY =
- "persist.sys.zram_enabled";
+ "persist.sys.zram_enabled";
+
+ private static final String ISOLATED_STORAGE_PROPERTY =
+ "persist.sys.isolated_storage";
+
+ private static final String SHARED_SANDBOX_ID_PREFIX = "shared:";
public static class Lifecycle extends SystemService {
private StorageManagerService mStorageManagerService;
@@ -267,6 +277,18 @@
*/
private final Object mLock = LockGuard.installNewLock(LockGuard.INDEX_STORAGE);
+ /**
+ * Similar to {@link #mLock}, never hold this lock while performing downcalls into vold.
+ * Also, never hold this while calling into PackageManagerService since it is used in callbacks
+ * from PackageManagerService.
+ *
+ * If both {@link #mLock} and this lock need to be held, {@link #mLock} should be acquired
+ * before this.
+ *
+ * Use -PL suffix for methods that need to called with this lock held.
+ */
+ private final Object mPackagesLock = new Object();
+
/** Set of users that we know are unlocked. */
@GuardedBy("mLock")
private int[] mLocalUnlockedUsers = EmptyArray.INT;
@@ -296,6 +318,15 @@
@GuardedBy("mLock")
private String mMoveTargetUuid;
+ @GuardedBy("mPackagesLock")
+ private final SparseArray<ArraySet<String>> mPackages = new SparseArray<>();
+
+ @GuardedBy("mPackagesLock")
+ private final ArrayMap<String, Integer> mAppIds = new ArrayMap<>();
+
+ @GuardedBy("mPackagesLock")
+ private final SparseArray<String> mSandboxIds = new SparseArray<>();
+
private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
/** Holding lock for AppFuse business */
@@ -417,6 +448,7 @@
private volatile boolean mSecureKeyguardShowing = true;
private PackageManagerService mPms;
+ private PackageManagerInternal mPmInternal;
private final Callbacks mCallbacks;
private final LockPatternUtils mLockPatternUtils;
@@ -868,12 +900,13 @@
try {
mVold.reset();
+ pushPackagesInfo();
// Tell vold about all existing and started users
for (UserInfo user : users) {
mVold.onUserAdded(user.id, user.serialNumber);
}
for (int userId : systemUnlockedUsers) {
- mVold.onUserStarted(userId);
+ mVold.onUserStarted(userId, getPackagesArrayForUser(userId));
mStoraged.onUserStarted(userId);
}
mVold.onSecureKeyguardStateChanged(mSecureKeyguardShowing);
@@ -890,7 +923,7 @@
// staging area is ready so it's ready for zygote-forked apps to
// bind mount against.
try {
- mVold.onUserStarted(userId);
+ mVold.onUserStarted(userId, getPackagesArrayForUser(userId));
mStoraged.onUserStarted(userId);
} catch (Exception e) {
Slog.wtf(TAG, e);
@@ -1396,6 +1429,7 @@
// XXX: This will go away soon in favor of IMountServiceObserver
mPms = (PackageManagerService) ServiceManager.getService("package");
+ mPmInternal = LocalServices.getService(PackageManagerInternal.class);
HandlerThread hthread = new HandlerThread(TAG);
hthread.start();
@@ -1445,9 +1479,99 @@
}
private void start() {
+ collectPackagesInfo();
connect();
}
+ private void collectPackagesInfo() {
+ if (!SystemProperties.getBoolean(ISOLATED_STORAGE_PROPERTY, false)) {
+ return;
+ }
+ resetPackageData();
+ final SparseArray<String> sharedUserIds = mPmInternal.getAppsWithSharedUserIds();
+ final int[] userIds = LocalServices.getService(
+ UserManagerInternal.class).getUserIds();
+ for (int userId : userIds) {
+ final List<ApplicationInfo> appInfos
+ = mContext.getPackageManager().getInstalledApplicationsAsUser(
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+ synchronized (mPackagesLock) {
+ final ArraySet<String> userPackages = getPackagesForUserPL(userId);
+ for (int i = appInfos.size() - 1; i >= 0; --i) {
+ if (appInfos.get(i).isInstantApp()) {
+ continue;
+ }
+ final String packageName = appInfos.get(i).packageName;
+ userPackages.add(packageName);
+
+ final int appId = UserHandle.getAppId(appInfos.get(i).uid);
+ mAppIds.put(packageName, appId);
+ mSandboxIds.put(appId, getSandboxId(packageName, sharedUserIds.get(appId)));
+ }
+ }
+ }
+ }
+
+ private void resetPackageData() {
+ synchronized (mPackagesLock) {
+ mPackages.clear();
+ mAppIds.clear();
+ mSandboxIds.clear();
+ }
+ }
+
+ private static String getSandboxId(String packageName, String sharedUserId) {
+ return sharedUserId == null ? packageName : SHARED_SANDBOX_ID_PREFIX + sharedUserId;
+ }
+ private void pushPackagesInfo() throws RemoteException {
+ if (!SystemProperties.getBoolean(ISOLATED_STORAGE_PROPERTY, false)) {
+ return;
+ }
+ // Arrays to fill up from {@link #mAppIds}
+ final String[] allPackageNames;
+ final int[] appIdsForPackages;
+
+ // Arrays to fill up from {@link #mSandboxIds}
+ final int[] allAppIds;
+ final String[] sandboxIdsForApps;
+ synchronized (mPackagesLock) {
+ allPackageNames = new String[mAppIds.size()];
+ appIdsForPackages = new int[mAppIds.size()];
+ for (int i = mAppIds.size() - 1; i >= 0; --i) {
+ allPackageNames[i] = mAppIds.keyAt(i);
+ appIdsForPackages[i] = mAppIds.valueAt(i);
+ }
+
+ allAppIds = new int[mSandboxIds.size()];
+ sandboxIdsForApps = new String[mSandboxIds.size()];
+ for (int i = mSandboxIds.size() - 1; i >= 0; --i) {
+ allAppIds[i] = mSandboxIds.keyAt(i);
+ sandboxIdsForApps[i] = mSandboxIds.valueAt(i);
+ }
+ }
+ mVold.addAppIds(allPackageNames, appIdsForPackages);
+ mVold.addSandboxIds(allAppIds, sandboxIdsForApps);
+ }
+
+ @GuardedBy("mPackagesLock")
+ private ArraySet<String> getPackagesForUserPL(int userId) {
+ ArraySet<String> userPackages = mPackages.get(userId);
+ if (userPackages == null) {
+ userPackages = new ArraySet<>();
+ mPackages.put(userId, userPackages);
+ }
+ return userPackages;
+ }
+
+ private String[] getPackagesArrayForUser(int userId) {
+ if (!SystemProperties.getBoolean(ISOLATED_STORAGE_PROPERTY, false)) {
+ return new String[0];
+ }
+ synchronized (mPackagesLock) {
+ return getPackagesForUserPL(userId).toArray(new String[0]);
+ }
+ }
+
private void connect() {
IBinder binder = ServiceManager.getService("storaged");
if (binder != null) {
@@ -3635,6 +3759,10 @@
@Override
public void onExternalStoragePolicyChanged(int uid, String packageName) {
+ // No runtime storage permissions in isolated storage world, so nothing to do here.
+ if (SystemProperties.getBoolean(ISOLATED_STORAGE_PROPERTY, false)) {
+ return;
+ }
final int mountMode = getExternalStorageMountMode(uid, packageName);
remountUidExternalStorage(uid, mountMode);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 29937ab..5bf6892 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -3658,7 +3658,7 @@
}
app = r.app;
- if (app != null && app.debugging) {
+ if (app != null && app.isDebugging()) {
// The app's being debugged; let it ride
return;
}
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index acdc738..73ffd5c 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -31,13 +32,18 @@
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
import static com.android.server.am.ActivityDisplayProto.CONFIGURATION_CONTAINER;
+import static com.android.server.am.ActivityDisplayProto.FOCUSED_STACK_ID;
import static com.android.server.am.ActivityDisplayProto.ID;
+import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY;
import static com.android.server.am.ActivityDisplayProto.STACKS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityStackSupervisor.TAG_STATES;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.WindowConfiguration;
@@ -153,15 +159,19 @@
onStackOrderChanged();
}
- void positionChildAtTop(ActivityStack stack) {
- positionChildAt(stack, mStacks.size());
+ void positionChildAtTop(ActivityStack stack, boolean includingParents) {
+ positionChildAt(stack, mStacks.size(), includingParents);
}
void positionChildAtBottom(ActivityStack stack) {
- positionChildAt(stack, 0);
+ positionChildAt(stack, 0, false /* includingParents */);
}
private void positionChildAt(ActivityStack stack, int position) {
+ positionChildAt(stack, position, false /* includingParents */);
+ }
+
+ private void positionChildAt(ActivityStack stack, int position, boolean includingParents) {
// TODO: Keep in sync with WindowContainer.positionChildAt(), once we change that to adjust
// the position internally, also update the logic here
mStacks.remove(stack);
@@ -173,7 +183,7 @@
// we don't have to call WindowContainerController#positionChildAt() here.
if (stack.getWindowContainerController() != null) {
mWindowContainerController.positionChildAt(stack.getWindowContainerController(),
- insertPosition);
+ insertPosition, includingParents);
}
onStackOrderChanged();
}
@@ -315,16 +325,6 @@
+ windowingMode);
}
- if (windowingMode == WINDOWING_MODE_UNDEFINED) {
- // TODO: Should be okay to have stacks with with undefined windowing mode long term, but
- // have to set them to something for now due to logic that depending on them.
- windowingMode = getWindowingMode(); // Put in current display's windowing mode
- if (windowingMode == WINDOWING_MODE_UNDEFINED) {
- // Else fullscreen for now...
- windowingMode = WINDOWING_MODE_FULLSCREEN;
- }
- }
-
final int stackId = getNextStackId();
return createStackUnchecked(windowingMode, activityType, stackId, onTop);
}
@@ -350,6 +350,45 @@
return null;
}
+ ActivityStack getNextFocusableStack() {
+ return getNextFocusableStack(null /* currentFocus */, false /* ignoreCurrent */);
+ }
+
+ ActivityStack getNextFocusableStack(ActivityStack currentFocus, boolean ignoreCurrent) {
+ final int currentWindowingMode = currentFocus != null
+ ? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
+
+ ActivityStack candidate = null;
+ for (int i = mStacks.size() - 1; i >= 0; --i) {
+ final ActivityStack stack = mStacks.get(i);
+ if (ignoreCurrent && stack == currentFocus) {
+ continue;
+ }
+ if (!stack.isFocusable() || !stack.shouldBeVisible(null)) {
+ continue;
+ }
+
+ if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
+ && candidate == null && stack.inSplitScreenPrimaryWindowingMode()) {
+ // If the currently focused stack is in split-screen secondary we save off the
+ // top primary split-screen stack as a candidate for focus because we might
+ // prefer focus to move to an other stack to avoid primary split-screen stack
+ // overlapping with a fullscreen stack when a fullscreen stack is higher in z
+ // than the next split-screen stack. Assistant stack, I am looking at you...
+ // We only move the focus to the primary-split screen stack if there isn't a
+ // better alternative.
+ candidate = stack;
+ continue;
+ }
+ if (candidate != null && stack.inSplitScreenSecondaryWindowingMode()) {
+ // Use the candidate stack since we are now at the secondary split-screen.
+ return candidate;
+ }
+ return stack;
+ }
+ return candidate;
+ }
+
ActivityRecord getResumedActivity() {
final ActivityStack focusedStack = getFocusedStack();
if (focusedStack == null) {
@@ -372,6 +411,30 @@
}
/**
+ * Pause all activities in either all of the stacks or just the back stacks.
+ * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
+ * @param resuming The resuming activity.
+ * @param dontWait The resuming activity isn't going to wait for all activities to be paused
+ * before resuming.
+ * @return true if any activity was paused as a result of this call.
+ */
+ boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
+ boolean someActivityPaused = false;
+ for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ // TODO(b/111541062): Check if resumed activity on this display instead
+ if (!mSupervisor.isTopDisplayFocusedStack(stack)
+ && stack.getResumedActivity() != null) {
+ if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
+ " mResumedActivity=" + stack.getResumedActivity());
+ someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
+ dontWait);
+ }
+ }
+ return someActivityPaused;
+ }
+
+ /**
* Removes stacks in the input windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
*/
@@ -578,7 +641,21 @@
windowingMode = getWindowingMode();
}
}
+ return validateWindowingMode(windowingMode, r, task, activityType);
+ }
+ /**
+ * Check that the requested windowing-mode is appropriate for the specified task and/or activity
+ * on this display.
+ *
+ * @param windowingMode The windowing-mode to validate.
+ * @param r The {@link ActivityRecord} to check against.
+ * @param task The {@link TaskRecord} to check against.
+ * @param activityType An activity type.
+ * @return The provided windowingMode or the closest valid mode which is appropriate.
+ */
+ int validateWindowingMode(int windowingMode, @Nullable ActivityRecord r,
+ @Nullable TaskRecord task, int activityType) {
// Make sure the windowing mode we are trying to use makes sense for what is supported.
final ActivityTaskManagerService service = mSupervisor.mService;
boolean supportsMultiWindow = service.mSupportsMultiWindow;
@@ -898,6 +975,16 @@
final long token = proto.start(fieldId);
super.writeToProto(proto, CONFIGURATION_CONTAINER, false /* trim */);
proto.write(ID, mDisplayId);
+ final ActivityStack focusedStack = getFocusedStack();
+ if (focusedStack != null) {
+ proto.write(FOCUSED_STACK_ID, focusedStack.mStackId);
+ final ActivityRecord focusedActivity = focusedStack.getDisplay().getResumedActivity();
+ if (focusedActivity != null) {
+ focusedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
+ }
+ } else {
+ proto.write(FOCUSED_STACK_ID, INVALID_STACK_ID);
+ }
for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = mStacks.get(stackNdx);
stack.writeToProto(proto, STACKS);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c48ebad..48d554c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -463,12 +463,6 @@
static final int BROADCAST_FG_TIMEOUT = 10*1000;
static final int BROADCAST_BG_TIMEOUT = 60*1000;
- // How long we wait until we timeout on key dispatching.
- static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
-
- // How long we wait until we timeout on key dispatching during instrumentation.
- static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
-
// Disable hidden API checks for the newly started instrumentation.
// Must be kept in sync with Am.
private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
@@ -574,8 +568,6 @@
final AppErrors mAppErrors;
- final AppWarnings mAppWarnings;
-
/**
* Dump of the activity state at the time of the last ANR. Cleared after
* {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
@@ -695,10 +687,42 @@
* All of the processes we currently have running organized by pid.
* The keys are the pid running the application.
*
- * <p>NOTE: This object is protected by its own lock, NOT the global
- * activity manager lock!
+ * <p>NOTE: This object is protected by its own lock, NOT the global activity manager lock!
*/
- final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
+ final PidMap mPidsSelfLocked = new PidMap();
+ final class PidMap {
+ private final SparseArray<ProcessRecord> mPidMap = new SparseArray<>();
+
+ void put(int key, ProcessRecord value) {
+ mPidMap.put(key, value);
+ mAtmInternal.onProcessMapped(key, value.getWindowProcessController());
+ }
+
+ void remove(int pid) {
+ mPidMap.remove(pid);
+ mAtmInternal.onProcessUnMapped(pid);
+ }
+
+ ProcessRecord get(int pid) {
+ return mPidMap.get(pid);
+ }
+
+ int size() {
+ return mPidMap.size();
+ }
+
+ ProcessRecord valueAt(int index) {
+ return mPidMap.valueAt(index);
+ }
+
+ int keyAt(int index) {
+ return mPidMap.keyAt(index);
+ }
+
+ int indexOfKey(int key) {
+ return mPidMap.indexOfKey(key);
+ }
+ }
/**
* All of the processes that have been forced to be important. The key
@@ -1425,7 +1449,6 @@
static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
static final int CLEAR_DNS_CACHE_MSG = 28;
static final int UPDATE_HTTP_PROXY_MSG = 29;
- static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
static final int REPORT_MEM_USAGE_MSG = 33;
@@ -1456,7 +1479,6 @@
static ServiceThread sKillThread = null;
static KillHandler sKillHandler = null;
- CompatModeDialog mCompatModeDialog;
long mLastMemUsageReportTime = 0;
/**
@@ -1587,34 +1609,6 @@
}
}
} break;
- case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
- synchronized (ActivityManagerService.this) {
- ActivityRecord ar = (ActivityRecord) msg.obj;
- if (mCompatModeDialog != null) {
- if (mCompatModeDialog.mAppInfo.packageName.equals(
- ar.info.applicationInfo.packageName)) {
- return;
- }
- mCompatModeDialog.dismiss();
- mCompatModeDialog = null;
- }
- if (ar != null && false) {
- if (mCompatModePackages.getPackageAskCompatModeLocked(
- ar.packageName)) {
- int mode = mCompatModePackages.computeCompatModeLocked(
- ar.info.applicationInfo);
- if (mode == ActivityManager.COMPAT_MODE_DISABLED
- || mode == ActivityManager.COMPAT_MODE_ENABLED) {
- mCompatModeDialog = new CompatModeDialog(
- ActivityManagerService.this, mUiContext,
- ar.info.applicationInfo);
- mCompatModeDialog.show();
- }
- }
- }
- }
- break;
- }
case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
dispatchProcessesChanged();
break;
@@ -2433,7 +2427,6 @@
mUiContext = null;
GL_ES_VERSION = 0;
mAppErrors = null;
- mAppWarnings = null;
mAppOpsService = mInjector.getAppOpsService(null, null);
mBatteryStatsService = null;
mCompatModePackages = null;
@@ -2500,8 +2493,6 @@
final File systemDir = SystemServiceManager.ensureSystemDir();
- mAppWarnings = new AppWarnings(this, mUiContext, mHandler, mUiHandler, systemDir);
-
// TODO: Move creation of battery stats service outside of activity manager service.
mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
mBatteryStatsService.getActiveStatistics().readLocked();
@@ -2891,28 +2882,6 @@
mActivityTaskManager.unregisterTaskStackListener(listener);
}
- final void showAskCompatModeDialogLocked(ActivityRecord r) {
- Message msg = Message.obtain();
- msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
- msg.obj = r.getTask().askedCompatMode ? null : r;
- mUiHandler.sendMessage(msg);
- }
-
- final AppWarnings getAppWarningsLocked() {
- return mAppWarnings;
- }
-
- /**
- * Shows app warning dialogs, if necessary.
- *
- * @param r activity record for which the warnings may be displayed
- */
- final void showAppWarningsIfNeededLocked(ActivityRecord r) {
- mAppWarnings.showUnsupportedCompileSdkDialogIfNeeded(r);
- mAppWarnings.showUnsupportedDisplaySizeDialogIfNeeded(r);
- mAppWarnings.showDeprecatedTargetDialogIfNeeded(r);
- }
-
private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
String what, Object obj, ProcessRecord srcApp) {
app.lastActivityTime = now;
@@ -3606,7 +3575,7 @@
// the package was initially frozen through KILL_APPLICATION_MSG, so
// it doesn't hurt to use it again.)
forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
- false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
+ false, true, false, false, app.userId, "start failure");
return false;
}
}
@@ -3635,8 +3604,8 @@
app.pendingStart = false;
return;
}
- app.usingWrapper = invokeWith != null
- || SystemProperties.get("wrap." + app.processName) != null;
+ app.setUsingWrapper(invokeWith != null
+ || SystemProperties.get("wrap." + app.processName) != null);
mPendingStarts.put(startSeq, app);
}
final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
@@ -3688,13 +3657,13 @@
startResult = startWebView(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
- app.info.dataDir, null,
+ app.info.dataDir, null, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
- app.info.dataDir, invokeWith,
+ app.info.dataDir, invokeWith, app.info.packageName,
new String[] {PROC_START_SEQ_IDENT + app.startSeq});
}
checkTime(startTime, "startProcess: returned from zygote!");
@@ -3732,7 +3701,7 @@
// Indicates that this process start has been taken care of.
if (mPendingStarts.get(expectedStartSeq) == null) {
if (pending.pid == startResult.pid) {
- pending.usingWrapper = startResult.usingWrapper;
+ pending.setUsingWrapper(startResult.usingWrapper);
// TODO: Update already existing clients of usingWrapper
}
return false;
@@ -3795,7 +3764,7 @@
}
reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
app.setPid(pid);
- app.usingWrapper = usingWrapper;
+ app.setUsingWrapper(usingWrapper);
app.pendingStart = false;
checkTime(app.startTime, "startProcess: starting to update pids map");
ProcessRecord oldApp;
@@ -3880,7 +3849,7 @@
aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
ProcessRecord app = getProcessRecordLocked(aInfo.processName,
aInfo.applicationInfo.uid, true);
- if (app == null || app.instr == null) {
+ if (app == null || app.getActiveInstrumentation() == null) {
intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
// For ANR debugging to verify if the user activity is the one that actually
@@ -4400,9 +4369,9 @@
app.clearRecentTasks();
app.clearActivities();
- if (app.instr != null) {
+ if (app.getActiveInstrumentation() != null) {
Slog.w(TAG, "Crash of app " + app.processName
- + " running instrumentation " + app.instr.mClass);
+ + " running instrumentation " + app.getActiveInstrumentation().mClass);
Bundle info = new Bundle();
info.putString("shortMsg", "Process crashed.");
finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
@@ -4411,7 +4380,7 @@
mWindowManager.deferSurfaceLayout();
try {
if (!restarting && hasVisibleActivities
- && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
+ && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
// If there was nothing to resume, and we are not already restarting this process, but
// there is a visible activity that is hosted by the process... then make sure all
// visible activities are running, taking care of restarting this process.
@@ -4556,7 +4525,7 @@
// Clean up already done if the process has been re-started.
if (app.pid == pid && app.thread != null &&
app.thread.asBinder() == thread.asBinder()) {
- boolean doLowMem = app.instr == null;
+ boolean doLowMem = app.getActiveInstrumentation() == null;
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
reportUidInfoMessageLocked(TAG,
@@ -5499,7 +5468,7 @@
// Clean-up disabled activities.
if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
packageName, disabledClasses, true, false, userId) && mBooted) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mStackSupervisor.scheduleIdleLocked();
}
@@ -5673,7 +5642,7 @@
}
}
if (mBooted) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mStackSupervisor.scheduleIdleLocked();
}
}
@@ -5885,7 +5854,7 @@
if (app == null && startSeq > 0) {
final ProcessRecord pending = mPendingStarts.get(startSeq);
if (pending != null && pending.startUid == callingUid
- && handleProcessStartedLocked(pending, pid, pending.usingWrapper,
+ && handleProcessStartedLocked(pending, pid, pending.isUsingWrapper(),
startSeq, true)) {
app = pending;
}
@@ -5939,7 +5908,7 @@
app.forcingToImportant = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
- app.debugging = false;
+ app.setDebugging(false);
app.cached = false;
app.killedByAm = false;
app.killed = false;
@@ -5976,7 +5945,7 @@
testMode = mWaitForDebugger
? ApplicationThreadConstants.DEBUG_WAIT
: ApplicationThreadConstants.DEBUG_ON;
- app.debugging = true;
+ app.setDebugging(true);
if (mDebugTransient) {
mDebugApp = mOrigDebugApp;
mWaitForDebugger = mOrigWaitForDebugger;
@@ -5998,13 +5967,15 @@
|| (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
}
- if (app.instr != null) {
- notifyPackageUse(app.instr.mClass.getPackageName(),
+ final ActiveInstrumentation instr = app.getActiveInstrumentation();
+
+ if (instr != null) {
+ notifyPackageUse(instr.mClass.getPackageName(),
PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
+ processName + " with config " + getGlobalConfiguration());
- ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
+ ApplicationInfo appInfo = instr != null ? instr.mTargetInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
ProfilerInfo profilerInfo = null;
@@ -6021,8 +5992,8 @@
preBindAgent = mProfilerInfo.agent;
}
}
- } else if (app.instr != null && app.instr.mProfileFile != null) {
- profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
+ } else if (instr != null && instr.mProfileFile != null) {
+ profilerInfo = new ProfilerInfo(instr.mProfileFile, null, 0, false, false,
null, false);
}
if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
@@ -6059,21 +6030,22 @@
// currently active instrumentation. (Note we do this AFTER all of the profiling
// stuff above because profiling can currently happen only in the primary
// instrumentation process.)
- if (mActiveInstrumentation.size() > 0 && app.instr == null) {
- for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
+ if (mActiveInstrumentation.size() > 0 && instr == null) {
+ for (int i = mActiveInstrumentation.size() - 1;
+ i >= 0 && app.getActiveInstrumentation() == null; i--) {
ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
if (aInstr.mTargetProcesses.length == 0) {
// This is the wildcard mode, where every process brought up for
// the target instrumentation should be included.
if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
- app.instr = aInstr;
+ app.setActiveInstrumentation(aInstr);
aInstr.mRunningProcesses.add(app);
}
} else {
for (String proc : aInstr.mTargetProcesses) {
if (proc.equals(app.processName)) {
- app.instr = aInstr;
+ app.setActiveInstrumentation(aInstr);
aInstr.mRunningProcesses.add(app);
break;
}
@@ -6103,16 +6075,17 @@
checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
+ final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
if (app.isolatedEntryPoint != null) {
// This is an isolated process which should just call an entry point instead of
// being bound to an application.
thread.runIsolatedEntryPoint(app.isolatedEntryPoint, app.isolatedEntryPointArgs);
- } else if (app.instr != null) {
+ } else if (instr2 != null) {
thread.bindApplication(processName, appInfo, providers,
- app.instr.mClass,
- profilerInfo, app.instr.mArguments,
- app.instr.mWatcher,
- app.instr.mUiAutomationConnection, testMode,
+ instr2.mClass,
+ profilerInfo, instr2.mArguments,
+ instr2.mWatcher,
+ instr2.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.isPersistent(),
new Configuration(getGlobalConfiguration()), app.compat,
@@ -9257,7 +9230,8 @@
if (proc == null) {
throw new SecurityException("Unknown process: " + callingPid);
}
- if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
+ if (proc.getActiveInstrumentation() == null
+ || proc.getActiveInstrumentation().mUiAutomationConnection == null) {
throw new SecurityException("Only an instrumentation process "
+ "with a UiAutomation can call setUserIsMonkey");
}
@@ -9380,89 +9354,6 @@
ActivityManager.BUGREPORT_OPTION_WIFI);
}
-
- public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
- if (r == null || !r.hasProcess()) {
- return KEY_DISPATCHING_TIMEOUT;
- }
- return getInputDispatchingTimeoutLocked((ProcessRecord) r.app.mOwner);
- }
-
- public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
- if (r != null && (r.instr != null || r.usingWrapper)) {
- return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
- }
- return KEY_DISPATCHING_TIMEOUT;
- }
-
- @Override
- public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
- if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires permission "
- + android.Manifest.permission.FILTER_EVENTS);
- }
- ProcessRecord proc;
- long timeout;
- synchronized (this) {
- synchronized (mPidsSelfLocked) {
- proc = mPidsSelfLocked.get(pid);
- }
- timeout = getInputDispatchingTimeoutLocked(proc);
- }
-
- if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
- return -1;
- }
-
- return timeout;
- }
-
- /**
- * Handle input dispatching timeouts.
- * Returns whether input dispatching should be aborted or not.
- */
- public boolean inputDispatchingTimedOut(final ProcessRecord proc,
- final ActivityRecord activity, final ActivityRecord parent,
- final boolean aboveSystem, String reason) {
- if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires permission "
- + android.Manifest.permission.FILTER_EVENTS);
- }
-
- final String annotation;
- if (reason == null) {
- annotation = "Input dispatching timed out";
- } else {
- annotation = "Input dispatching timed out (" + reason + ")";
- }
-
- if (proc != null) {
- synchronized (this) {
- if (proc.debugging) {
- return false;
- }
-
- if (proc.instr != null) {
- Bundle info = new Bundle();
- info.putString("shortMsg", "keyDispatchingTimedOut");
- info.putString("longMsg", annotation);
- finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
- return true;
- }
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
- }
- });
- }
-
- return true;
- }
-
public void registerProcessObserver(IProcessObserver observer) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"registerProcessObserver()");
@@ -10307,7 +10198,7 @@
} finally {
Binder.restoreCallingIdentity(ident);
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
@@ -10406,6 +10297,15 @@
: StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
);
+ final int relaunchReason = r == null ? ActivityRecord.RELAUNCH_REASON_NONE
+ : r.getWindowProcessController().computeRelaunchReason();
+ final String relaunchReasonString = ActivityRecord.relaunchReasonToString(relaunchReason);
+ if (crashInfo.crashTag == null) {
+ crashInfo.crashTag = relaunchReasonString;
+ } else {
+ crashInfo.crashTag = crashInfo.crashTag + " " + relaunchReasonString;
+ }
+
addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
mAppErrors.crashApplication(r, crashInfo);
@@ -10578,15 +10478,6 @@
StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
callingPid);
- final int relaunchReason = r == null ? ActivityRecord.RELAUNCH_REASON_NONE
- : r.getWindowProcessController().computeRelaunchReason();
- final String relaunchReasonString = ActivityRecord.relaunchReasonToString(relaunchReason);
- if (crashInfo.crashTag == null) {
- crashInfo.crashTag = relaunchReasonString;
- } else {
- crashInfo.crashTag = crashInfo.crashTag + " " + relaunchReasonString;
- }
-
addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
return r;
@@ -16425,7 +16316,7 @@
mActivityTaskManager.getRecentTasks().removeTasksByPackageName(ssp, userId);
mServices.forceStopPackageLocked(ssp, userId);
- mAppWarnings.onPackageUninstalled(ssp);
+ mAtmInternal.onPackageUninstalled(ssp);
mCompatModePackages.handlePackageUninstalledLocked(ssp);
mBatteryStatsService.notePackageUninstalled(ssp);
}
@@ -16506,7 +16397,7 @@
String ssp;
if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
mCompatModePackages.handlePackageDataClearedLocked(ssp);
- mAppWarnings.onPackageDataCleared(ssp);
+ mAtmInternal.onPackageDataCleared(ssp);
}
break;
}
@@ -17137,7 +17028,7 @@
ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
abiOverride);
- app.instr = activeInstr;
+ app.setActiveInstrumentation(activeInstr);
activeInstr.mFinished = false;
activeInstr.mRunningProcesses.add(app);
if (!mActiveInstrumentation.contains(activeInstr)) {
@@ -17170,16 +17061,17 @@
}
void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
- if (app.instr == null) {
+ final ActiveInstrumentation instr = app.getActiveInstrumentation();
+ if (instr == null) {
Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
return;
}
- if (!app.instr.mFinished && results != null) {
- if (app.instr.mCurResults == null) {
- app.instr.mCurResults = new Bundle(results);
+ if (!instr.mFinished && results != null) {
+ if (instr.mCurResults == null) {
+ instr.mCurResults = new Bundle(results);
} else {
- app.instr.mCurResults.putAll(results);
+ instr.mCurResults.putAll(results);
}
}
}
@@ -17205,37 +17097,38 @@
@GuardedBy("this")
void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
- if (app.instr == null) {
+ final ActiveInstrumentation instr = app.getActiveInstrumentation();
+ if (instr == null) {
Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
return;
}
- if (!app.instr.mFinished) {
- if (app.instr.mWatcher != null) {
- Bundle finalResults = app.instr.mCurResults;
+ if (!instr.mFinished) {
+ if (instr.mWatcher != null) {
+ Bundle finalResults = instr.mCurResults;
if (finalResults != null) {
- if (app.instr.mCurResults != null && results != null) {
+ if (instr.mCurResults != null && results != null) {
finalResults.putAll(results);
}
} else {
finalResults = results;
}
- mInstrumentationReporter.reportFinished(app.instr.mWatcher,
- app.instr.mClass, resultCode, finalResults);
+ mInstrumentationReporter.reportFinished(instr.mWatcher,
+ instr.mClass, resultCode, finalResults);
}
// Can't call out of the system process with a lock held, so post a message.
- if (app.instr.mUiAutomationConnection != null) {
+ if (instr.mUiAutomationConnection != null) {
mAppOpsService.setAppOpsServiceDelegate(null);
getPackageManagerInternalLocked().setCheckPermissionDelegate(null);
mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
- app.instr.mUiAutomationConnection).sendToTarget();
+ instr.mUiAutomationConnection).sendToTarget();
}
- app.instr.mFinished = true;
+ instr.mFinished = true;
}
- app.instr.removeProcess(app);
- app.instr = null;
+ instr.removeProcess(app);
+ app.setActiveInstrumentation(null);
forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
"finished inst");
@@ -17709,7 +17602,7 @@
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app);
}
- } else if (app.instr != null) {
+ } else if (app.getActiveInstrumentation() != null) {
// Don't want to kill running instrumentation.
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
@@ -21208,6 +21101,13 @@
return ActivityManagerService.this.getHomeIntent();
}
}
+
+ @Override
+ public void scheduleAppGcs() {
+ synchronized (ActivityManagerService.this) {
+ ActivityManagerService.this.scheduleAppGcsLocked();
+ }
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 19ea955..67abedc 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -1036,7 +1036,7 @@
(info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0, info.configChanges,
task.voiceSession != null, mLaunchTaskBehind, isAlwaysFocusable(),
appInfo.targetSdkVersion, mRotationAnimationHint,
- ActivityManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
+ ActivityTaskManagerService.getInputDispatchingTimeoutLocked(this) * 1000000L);
task.addActivityToTop(this);
@@ -1941,7 +1941,7 @@
} else {
if (deferRelaunchUntilPaused) {
stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
} else {
mStackSupervisor.updatePreviousProcessLocked(this);
}
@@ -2134,7 +2134,7 @@
mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */,
false /* remove */, true /* processPausingActivities */);
}
- service.mAm.scheduleAppGcsLocked();
+ service.scheduleAppGcsLocked();
}
}
}
@@ -2159,13 +2159,11 @@
!hasProcess() || app.getPid() == windowPid || windowPid == -1;
}
if (windowFromSameProcessAsActivity) {
- return service.mAm.inputDispatchingTimedOut(
- (ProcessRecord) anrApp.mOwner, anrActivity, this, false, reason);
+ return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
} else {
// In this case another process added windows using this activity token. So, we call the
// generic service input dispatch timed out method so that the right process is blamed.
- return service.mAm.inputDispatchingTimedOut(
- windowPid, false /* aboveSystem */, reason) < 0;
+ return service.inputDispatchingTimedOut(windowPid, false /* aboveSystem */, reason) < 0;
}
}
@@ -2364,7 +2362,7 @@
frozenBeforeDestroy = true;
if (!service.updateDisplayOverrideConfigurationLocked(config, this,
false /* deferResume */, displayId)) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
service.getTaskChangeNotificationController().notifyActivityRequestedOrientationChanged(
@@ -2819,10 +2817,12 @@
}
results = null;
newIntents = null;
- service.mAm.getAppWarningsLocked().onResumeActivity(this);
- service.mAm.showAskCompatModeDialogLocked(this);
+ service.getAppWarningsLocked().onResumeActivity(this);
} else {
- service.mAm.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
+ final ActivityStack stack = getStack();
+ if (stack != null) {
+ stack.mHandler.removeMessages(PAUSE_TIMEOUT_MSG, this);
+ }
setState(PAUSED, "relaunchActivityLocked");
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 058c714..54f87ce 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -497,7 +497,10 @@
if (DEBUG_STACK) Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:"
+ reason);
setResumedActivity(record, reason + " - onActivityStateChanged");
- mService.setResumedActivityUncheckLocked(record, reason);
+ if (record == mStackSupervisor.getTopResumedActivity()) {
+ // TODO(b/111541062): Support tracking multiple resumed activities
+ mService.setResumedActivityUncheckLocked(record, reason);
+ }
mStackSupervisor.mRecentTasks.add(record.getTask());
}
}
@@ -518,7 +521,7 @@
// Since always on top is only on when the stack is freeform or pinned, the state
// can be toggled when the windowing mode changes. We must make sure the stack is
// placed properly when always on top state changes.
- display.positionChildAtTop(this);
+ display.positionChildAtTop(this, false /* includingParents */);
}
}
@@ -537,15 +540,17 @@
final ActivityStack splitScreenStack = display.getSplitScreenPrimaryStack();
mTmpOptions.setLaunchWindowingMode(preferredWindowingMode);
+ int windowingMode = preferredWindowingMode;
// Need to make sure windowing mode is supported. If we in the process of creating the stack
// no need to resolve the windowing mode again as it is already resolved to the right mode.
- int windowingMode = creating
- ? preferredWindowingMode
- : display.resolveWindowingMode(
- null /* ActivityRecord */, mTmpOptions, topTask, getActivityType());
- if (splitScreenStack == this && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
- // Resolution to split-screen secondary for the primary split-screen stack means we want
- // to go fullscreen.
+ if (!creating) {
+ windowingMode = display.validateWindowingMode(windowingMode,
+ null /* ActivityRecord */, topTask, getActivityType());
+ }
+ if (splitScreenStack == this
+ && windowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) {
+ // Resolution to split-screen secondary for the primary split-screen stack means
+ // we want to go fullscreen.
windowingMode = WINDOWING_MODE_FULLSCREEN;
}
@@ -595,6 +600,9 @@
mStackSupervisor.mNoAnimActivities.add(topActivity);
}
super.setWindowingMode(windowingMode);
+ // setWindowingMode triggers an onConfigurationChanged cascade which can result in a
+ // different resolved windowing mode (usually when preferredWindowingMode is UNDEFINED).
+ windowingMode = getWindowingMode();
if (creating) {
// Nothing else to do if we don't have a window container yet. E.g. call from ctor.
@@ -621,15 +629,6 @@
mTmpRect2.setEmpty();
if (windowingMode != WINDOWING_MODE_FULLSCREEN) {
mWindowContainerController.getRawBounds(mTmpRect2);
- if (windowingMode == WINDOWING_MODE_FREEFORM) {
- if (topTask != null) {
- // TODO: Can we consolidate this and other sites that call this methods?
- Rect bounds = topTask().getLaunchBounds();
- if (bounds != null) {
- mTmpRect2.set(bounds);
- }
- }
- }
}
if (!Objects.equals(getOverrideBounds(), mTmpRect2)) {
@@ -663,7 +662,7 @@
if (!deferEnsuringVisibility) {
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
@@ -696,7 +695,7 @@
mWindowContainerController.reparent(activityDisplay.mDisplayId, mTmpRect2, onTop);
postAddToDisplay(activityDisplay, mTmpRect2.isEmpty() ? null : mTmpRect2, onTop);
adjustFocusToNextFocusableStack("reparent", true /* allowFocusSelf */);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
// Update visibility of activities before notifying WM. This way it won't try to resize
// windows that are no longer visible.
mStackSupervisor.ensureActivitiesVisibleLocked(null /* starting */, 0 /* configChanges */,
@@ -1058,7 +1057,7 @@
mStackSupervisor.moveHomeStackToFront(reason + " returnToHome");
}
- display.positionChildAtTop(this);
+ display.positionChildAtTop(this, true /* includingParents */);
mStackSupervisor.setFocusStackUnchecked(reason, this);
if (task != null) {
// This also moves the entire hierarchy branch to top, including parents
@@ -1445,7 +1444,7 @@
if (prev == null) {
if (resuming == null) {
Slog.wtf(TAG, "Trying to pause when nothing is resumed");
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
return false;
}
@@ -1525,7 +1524,7 @@
// pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
if (resuming == null) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
return false;
}
@@ -1619,7 +1618,7 @@
if (resumeNext) {
final ActivityStack topStack = mStackSupervisor.getTopDisplayFocusedStack();
if (!topStack.shouldSleepOrShutDownActivities()) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked(topStack, prev, null);
} else {
checkReadyForSleep();
ActivityRecord top = topStack.topRunningActivityLocked();
@@ -1628,7 +1627,7 @@
// something. Also if the top activity on the stack is not the just paused
// activity, we need to go ahead and resume it to ensure we complete an
// in-flight app switch.
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
}
@@ -2307,7 +2306,7 @@
*
* NOTE: It is not safe to call this method directly as it can cause an activity in a
* non-focused stack to be resumed.
- * Use {@link ActivityStackSupervisor#resumeFocusedStackTopActivityLocked} to resume the
+ * Use {@link ActivityStackSupervisor#resumeFocusedStacksTopActivitiesLocked} to resume the
* right activity for the current system state.
*/
@GuardedBy("mService")
@@ -2470,7 +2469,7 @@
final boolean resumeWhilePausing = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0
&& !lastResumedCanPip;
- boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
+ boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityLocked: Pausing " + mResumedActivity);
@@ -2659,7 +2658,7 @@
// the screen based on the new activity order.
boolean notUpdated = true;
- if (mStackSupervisor.isTopDisplayFocusedStack(this)) {
+ if (isFocusedStackOnDisplay()) {
// We have special rotation behavior when here is some active activity that
// requests specific orientation or Keyguard is locked. Make sure all activity
// visibilities are set correctly as well as the transition is updated if needed
@@ -2722,8 +2721,7 @@
next.shortComponentName);
next.sleeping = false;
- mService.mAm.getAppWarningsLocked().onResumeActivity(next);
- mService.mAm.showAskCompatModeDialogLocked(next);
+ mService.getAppWarningsLocked().onResumeActivity(next);
next.app.setPendingUiCleanAndForceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
transaction.setLifecycleStateRequest(
@@ -2792,12 +2790,13 @@
private boolean resumeTopActivityInNextFocusableStack(ActivityRecord prev,
ActivityOptions options, String reason) {
- if (adjustFocusToNextFocusableStack(reason)) {
+ final ActivityStack nextFocusedStack = adjustFocusToNextFocusableStack(reason);
+ if (nextFocusedStack != null) {
// Try to move focus to the next visible stack with a running activity if this
// stack is not covering the entire screen or is on a secondary display (with no home
// stack).
- return mStackSupervisor.resumeFocusedStackTopActivityLocked(
- mStackSupervisor.getTopDisplayFocusedStack(), prev, null);
+ return mStackSupervisor.resumeFocusedStacksTopActivitiesLocked(nextFocusedStack, prev,
+ null /* targetOptions */);
}
// Let's just start up the Launcher...
@@ -2810,20 +2809,6 @@
mStackSupervisor.resumeHomeStackTask(prev, reason);
}
- private TaskRecord getNextTask(TaskRecord targetTask) {
- final int index = mTaskHistory.indexOf(targetTask);
- if (index >= 0) {
- final int numTasks = mTaskHistory.size();
- for (int i = index + 1; i < numTasks; ++i) {
- TaskRecord task = mTaskHistory.get(i);
- if (task.userId == targetTask.userId) {
- return task;
- }
- }
- }
- return null;
- }
-
/** Returns the position the input task should be placed in this stack. */
int getAdjustedPositionForTask(TaskRecord task, int suggestedPosition,
ActivityRecord starting) {
@@ -3438,7 +3423,7 @@
}
// Move focus to next focusable stack if possible.
- if (adjustFocusToNextFocusableStack(myReason)) {
+ if (adjustFocusToNextFocusableStack(myReason) != null) {
return;
}
@@ -3446,21 +3431,25 @@
mStackSupervisor.moveHomeStackTaskToTop(myReason);
}
- /** Find next proper focusable stack and make it focused. */
- boolean adjustFocusToNextFocusableStack(String reason) {
+ /**
+ * Find next proper focusable stack and make it focused.
+ * @return The stack that now got the focus, {@code null} if none found.
+ */
+ ActivityStack adjustFocusToNextFocusableStack(String reason) {
return adjustFocusToNextFocusableStack(reason, false /* allowFocusSelf */);
}
/**
* Find next proper focusable stack and make it focused.
* @param allowFocusSelf Is the focus allowed to remain on the same stack.
+ * @return The stack that now got the focus, {@code null} if none found.
*/
- private boolean adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
+ private ActivityStack adjustFocusToNextFocusableStack(String reason, boolean allowFocusSelf) {
final ActivityStack stack =
mStackSupervisor.getNextFocusableStackLocked(this, !allowFocusSelf);
final String myReason = reason + " adjustFocusToNextFocusableStack";
if (stack == null) {
- return false;
+ return null;
}
final ActivityRecord top = stack.topRunningActivityLocked();
@@ -3468,11 +3457,12 @@
if (stack.isActivityTypeHome() && (top == null || !top.visible)) {
// If we will be focusing on the home stack next and its current top activity isn't
// visible, then use the move the home stack task to top to make the activity visible.
- return mStackSupervisor.moveHomeStackTaskToTop(reason);
+ mStackSupervisor.moveHomeStackTaskToTop(reason);
+ return stack;
}
stack.moveToFront(myReason);
- return true;
+ return stack;
}
final void stopActivityLocked(ActivityRecord r) {
@@ -3878,7 +3868,7 @@
false /* markFrozenIfConfigChanged */, true /* deferResume */);
}
if (activityRemoved) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
if (DEBUG_CONTAINERS) Slog.d(TAG_CONTAINERS,
"destroyActivityLocked: finishCurrentActivityLocked r=" + r +
@@ -3891,7 +3881,7 @@
if (DEBUG_ALL) Slog.v(TAG, "Enqueueing pending finish: " + r);
mStackSupervisor.mFinishingActivities.add(r);
r.resumeKeyDispatchingLocked();
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
return r;
}
@@ -4237,7 +4227,7 @@
}
}
if (activityRemoved) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
@@ -4432,7 +4422,7 @@
}
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
private void removeHistoryRecordsForAppLocked(ArrayList<ActivityRecord> list,
@@ -4665,7 +4655,7 @@
topActivity.supportsEnterPipOnTaskSwitch = true;
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
EventLog.writeEvent(EventLogTags.AM_TASK_TO_FRONT, tr.userId, tr.taskId);
mService.getTaskChangeNotificationController().notifyTaskMovedToFront(tr.taskId);
@@ -4736,7 +4726,7 @@
return true;
}
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
return true;
}
@@ -4783,7 +4773,7 @@
if (updatedConfig) {
// Ensure the resumed state of the focus activity if we updated the configuration of
// any activity.
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
@@ -4814,13 +4804,16 @@
final TaskRecord task = mTaskHistory.get(i);
if (task.isResizeable()) {
if (inFreeformWindowingMode()) {
- // TODO: Can be removed now since each freeform task is in its own stack.
+ // TODO(b/71028874): Can be removed since each freeform task is its own
+ // stack.
// For freeform stack we don't adjust the size of the tasks to match that
// of the stack, but we do try to make sure the tasks are still contained
// with the bounds of the stack.
- mTmpRect2.set(task.getOverrideBounds());
- fitWithinBounds(mTmpRect2, bounds);
- task.updateOverrideConfiguration(mTmpRect2);
+ if (task.getOverrideBounds() != null) {
+ mTmpRect2.set(task.getOverrideBounds());
+ fitWithinBounds(mTmpRect2, bounds);
+ task.updateOverrideConfiguration(mTmpRect2);
+ }
} else {
task.updateOverrideConfiguration(taskBounds, insetBounds);
}
@@ -5183,7 +5176,7 @@
if (isOnHomeDisplay() && mode != REMOVE_TASK_MODE_MOVING_TO_TOP
&& mStackSupervisor.isTopDisplayFocusedStack(this)) {
String myReason = reason + " leftTaskHistoryEmpty";
- if (!inMultiWindowMode() || !adjustFocusToNextFocusableStack(myReason)) {
+ if (!inMultiWindowMode() || adjustFocusToNextFocusableStack(myReason) == null) {
mStackSupervisor.moveHomeStackToFront(myReason);
}
}
@@ -5288,7 +5281,7 @@
// The task might have already been running and its visibility needs to be synchronized with
// the visibility of the stack / windows.
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
private ActivityStack preAddTask(TaskRecord task, String reason, boolean toTop) {
@@ -5328,7 +5321,7 @@
// always on top windows. Since the position the stack should be inserted into is calculated
// properly in {@link ActivityDisplay#getTopInsertPosition()} in both cases, we can just
// request that the stack is put at top here.
- display.positionChildAtTop(this);
+ display.positionChildAtTop(this, false /* includingParents */);
}
void moveToFrontAndResumeStateIfNeeded(ActivityRecord r, boolean moveToFront, boolean setResume,
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a732575..d1585cf 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -17,10 +17,8 @@
package com.android.server.am;
import static android.Manifest.permission.ACTIVITY_EMBEDDING;
-import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.START_ANY_ACTIVITY;
-import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
@@ -76,7 +74,6 @@
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
import static com.android.server.am.ActivityRecord.RELAUNCH_REASON_NONE;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
-import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
@@ -201,8 +198,8 @@
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
private static final String TAG_STACK = TAG + POSTFIX_STACK;
- private static final String TAG_STATES = TAG + POSTFIX_STATES;
private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
+ static final String TAG_STATES = TAG + POSTFIX_STATES;
static final String TAG_TASKS = TAG + POSTFIX_TASKS;
/** How long we wait until giving up on the last activity telling us it is idle. */
@@ -821,7 +818,7 @@
// Only resume home activity if isn't finishing.
if (r != null && !r.finishing) {
moveFocusableActivityStackToFrontLocked(r, myReason);
- return resumeFocusedStackTopActivityLocked(mHomeStack, prev, null);
+ return resumeFocusedStacksTopActivitiesLocked(mHomeStack, prev, null);
}
return mService.mAm.startHomeActivityLocked(mCurrentUser, myReason);
}
@@ -1119,16 +1116,8 @@
boolean pauseBackStacks(boolean userLeaving, ActivityRecord resuming, boolean dontWait) {
boolean someActivityPaused = false;
for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
- for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getChildAt(stackNdx);
- if (!isTopDisplayFocusedStack(stack) && stack.getResumedActivity() != null) {
- if (DEBUG_STATES) Slog.d(TAG_STATES, "pauseBackStacks: stack=" + stack +
- " mResumedActivity=" + stack.getResumedActivity());
- someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,
- dontWait);
- }
- }
+ someActivityPaused |= mActivityDisplays.valueAt(displayNdx)
+ .pauseBackStacks(userLeaving, resuming, dontWait);
}
return someActivityPaused;
}
@@ -1400,7 +1389,7 @@
// (e.g. AMS.startActivityAsUser).
final long token = Binder.clearCallingIdentity();
try {
- return mService.mAm.getPackageManagerInternalLocked().resolveIntent(
+ return mService.getPackageManagerInternalLocked().resolveIntent(
intent, resolvedType, modifiedFlags, userId, true, filterCallingUid);
} finally {
Binder.restoreCallingIdentity(token);
@@ -1523,8 +1512,7 @@
PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
r.sleeping = false;
r.forceNewConfig = false;
- mService.mAm.getAppWarningsLocked().onStartActivity(r);
- mService.mAm.showAskCompatModeDialogLocked(r);
+ mService.getAppWarningsLocked().onStartActivity(r);
r.compat = mService.mAm.compatibilityInfoForPackageLocked(r.info.applicationInfo);
ProfilerInfo profilerInfo = null;
if (mService.mAm.mProfileApp != null && mService.mAm.mProfileApp.equals(app.processName)) {
@@ -2109,7 +2097,7 @@
if (allResumedActivitiesIdle()) {
if (r != null) {
- mService.mAm.scheduleAppGcsLocked();
+ mService.scheduleAppGcsLocked();
}
if (mLaunchingActivity.isHeld()) {
@@ -2176,7 +2164,7 @@
//mWindowManager.dump();
if (activityRemoved) {
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
}
return r;
@@ -2272,28 +2260,35 @@
}
}
- boolean resumeFocusedStackTopActivityLocked() {
- return resumeFocusedStackTopActivityLocked(null, null, null);
+ boolean resumeFocusedStacksTopActivitiesLocked() {
+ return resumeFocusedStacksTopActivitiesLocked(null, null, null);
}
- boolean resumeFocusedStackTopActivityLocked(
+ boolean resumeFocusedStacksTopActivitiesLocked(
ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
if (!readyToResume()) {
return false;
}
- if (targetStack != null && isTopDisplayFocusedStack(targetStack)) {
+ if (targetStack != null && targetStack.isTopStackOnDisplay()) {
return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
- final ActivityStack focusedStack = getTopDisplayFocusedStack();
- final ActivityRecord r = focusedStack.topRunningActivityLocked();
- if (r == null || !r.isState(RESUMED)) {
- focusedStack.resumeTopActivityUncheckedLocked(null, null);
- } else if (r.isState(RESUMED)) {
- // Kick off any lingering app transitions form the MoveTaskToFront operation.
- focusedStack.executeAppTransition(targetOptions);
+ // Resume all top activities in focused stacks on all displays.
+ for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
+ final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
+ final ActivityStack focusedStack = display.getFocusedStack();
+ if (focusedStack == null) {
+ continue;
+ }
+ final ActivityRecord r = focusedStack.topRunningActivityLocked();
+ if (r == null || !r.isState(RESUMED)) {
+ focusedStack.resumeTopActivityUncheckedLocked(null, null);
+ } else if (r.isState(RESUMED)) {
+ // Kick off any lingering app transitions form the MoveTaskToFront operation.
+ focusedStack.executeAppTransition(targetOptions);
+ }
}
return false;
@@ -2344,6 +2339,9 @@
}
}
+ /**
+ * This doesn't just find a task, it also moves the task to front.
+ */
void findTaskToMoveToFront(TaskRecord task, int flags, ActivityOptions options, String reason,
boolean forceNonResizeable) {
final ActivityStack currentStack = task.getStack();
@@ -2613,74 +2611,58 @@
case ACTIVITY_TYPE_RECENTS: return r.isActivityTypeRecents();
case ACTIVITY_TYPE_ASSISTANT: return r.isActivityTypeAssistant();
}
- switch (stack.getWindowingMode()) {
- case WINDOWING_MODE_FULLSCREEN: return true;
- case WINDOWING_MODE_FREEFORM: return r.supportsFreeform();
- case WINDOWING_MODE_PINNED: return r.supportsPictureInPicture();
- case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY: return r.supportsSplitScreenWindowingMode();
- case WINDOWING_MODE_SPLIT_SCREEN_SECONDARY: return r.supportsSplitScreenWindowingMode();
+ // There is a 1-to-1 relationship between stack and task when not in
+ // primary split-windowing mode.
+ if (stack.getWindowingMode() != WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+ return false;
+ } else {
+ return r.supportsSplitScreenWindowingMode();
}
-
- if (!stack.isOnHomeDisplay()) {
- return r.canBeLaunchedOnDisplay(displayId);
- }
- Slog.e(TAG, "isValidLaunchStack: Unexpected stack=" + stack);
- return false;
}
/**
- * Get next focusable stack in the system. This will search across displays and stacks
- * in last-focused order for a focusable and visible stack, different from the target stack.
+ * Get next focusable stack in the system. This will search through the stack on the same
+ * display as the current focused stack, looking for a focusable and visible stack, different
+ * from the target stack. If no valid candidates will be found, it will then go through all
+ * displays and stacks in last-focused order.
*
* @param currentFocus The stack that previously had focus.
* @param ignoreCurrent If we should ignore {@param currentFocus} when searching for next
* candidate.
- * @return Next focusable {@link ActivityStack}, null if not found.
+ * @return Next focusable {@link ActivityStack}, {@code null} if not found.
*/
- ActivityStack getNextFocusableStackLocked(ActivityStack currentFocus, boolean ignoreCurrent) {
- mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
+ ActivityStack getNextFocusableStackLocked(@NonNull ActivityStack currentFocus,
+ boolean ignoreCurrent) {
+ // First look for next focusable stack on the same display
+ final ActivityDisplay preferredDisplay = currentFocus.getDisplay();
+ final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
+ currentFocus, ignoreCurrent);
+ if (preferredFocusableStack != null) {
+ return preferredFocusableStack;
+ }
- final int currentWindowingMode = currentFocus != null
- ? currentFocus.getWindowingMode() : WINDOWING_MODE_UNDEFINED;
- ActivityStack candidate = null;
+ // Now look through all displays
+ mWindowManager.getDisplaysInFocusOrder(mTmpOrderedDisplayIds);
for (int i = mTmpOrderedDisplayIds.size() - 1; i >= 0; --i) {
final int displayId = mTmpOrderedDisplayIds.get(i);
+ if (displayId == preferredDisplay.mDisplayId) {
+ // We've already checked this one
+ continue;
+ }
// If a display is registered in WM, it must also be available in AM.
final ActivityDisplay display = getActivityDisplayOrCreateLocked(displayId);
if (display == null) {
// Looks like the display no longer exists in the system...
continue;
}
- for (int j = display.getChildCount() - 1; j >= 0; --j) {
- final ActivityStack stack = display.getChildAt(j);
- if (ignoreCurrent && stack == currentFocus) {
- continue;
- }
- if (!stack.isFocusable() || !stack.shouldBeVisible(null)) {
- continue;
- }
-
- if (currentWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
- && candidate == null && stack.inSplitScreenPrimaryWindowingMode()) {
- // If the currently focused stack is in split-screen secondary we save off the
- // top primary split-screen stack as a candidate for focus because we might
- // prefer focus to move to an other stack to avoid primary split-screen stack
- // overlapping with a fullscreen stack when a fullscreen stack is higher in z
- // than the next split-screen stack. Assistant stack, I am looking at you...
- // We only move the focus to the primary-split screen stack if there isn't a
- // better alternative.
- candidate = stack;
- continue;
- }
- if (candidate != null && stack.inSplitScreenSecondaryWindowingMode()) {
- // Use the candidate stack since we are now at the secondary split-screen.
- return candidate;
- }
- return stack;
+ final ActivityStack nextFocusableStack = display.getNextFocusableStack(currentFocus,
+ ignoreCurrent);
+ if (nextFocusableStack != null) {
+ return nextFocusableStack;
}
}
- return candidate;
+ return null;
}
/**
@@ -2879,7 +2861,7 @@
}
ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
} finally {
mAllowDockedStackResize = true;
mWindowManager.continueSurfaceLayout();
@@ -3436,7 +3418,7 @@
// drawn signal is scheduled after the bounds animation start call on the bounds animator
// thread.
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
mService.getTaskChangeNotificationController().notifyActivityPinned(r);
}
@@ -3467,6 +3449,11 @@
"moveActivityStackToFront: r=" + r);
stack.moveToFront(reason, task);
+ // Report top activity change to tracking services and WM
+ if (r == getTopResumedActivity()) {
+ // TODO(b/111541062): Support tracking multiple resumed activities
+ mService.setResumedActivityUncheckLocked(r, reason);
+ }
return true;
}
@@ -3623,7 +3610,7 @@
// It is possible that the display will not be awake at the time we
// process the keyguard going away, which can happen before the sleep token
// is released. As a result, it is important we resume the activity here.
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
}
}
}
@@ -4729,7 +4716,7 @@
} break;
case RESUME_TOP_ACTIVITY_MSG: {
synchronized (mService.mGlobalLock) {
- resumeFocusedStackTopActivityLocked();
+ resumeFocusedStacksTopActivitiesLocked();
}
} break;
case SLEEP_TIMEOUT_MSG: {
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index ca12716..177e2f5 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -237,7 +237,7 @@
(mAInfo.applicationInfo.flags & FLAG_SUSPENDED) == 0) {
return false;
}
- final PackageManagerInternal pmi = mService.mAm.getPackageManagerInternalLocked();
+ final PackageManagerInternal pmi = mService.getPackageManagerInternalLocked();
if (pmi == null) {
return false;
}
@@ -318,7 +318,7 @@
private boolean interceptHarmfulAppIfNeeded() {
CharSequence harmfulAppWarning;
try {
- harmfulAppWarning = mService.mAm.getPackageManager()
+ harmfulAppWarning = mService.getPackageManager()
.getHarmfulAppWarning(mAInfo.packageName, mUserId);
} catch (RemoteException ex) {
return false;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 8be5ada..05fae83 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -672,7 +672,7 @@
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
try {
intent.addCategory(Intent.CATEGORY_VOICE);
- if (!mService.mAm.getPackageManager().activitySupportsIntent(
+ if (!mService.getPackageManager().activitySupportsIntent(
intent.getComponent(), intent, resolvedType)) {
Slog.w(TAG,
"Activity being started in current voice task does not support voice: "
@@ -690,7 +690,7 @@
// If the caller is starting a new voice session, just make sure the target
// is actually allowing it to run this way.
try {
- if (!mService.mAm.getPackageManager().activitySupportsIntent(intent.getComponent(),
+ if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
intent, resolvedType)) {
Slog.w(TAG,
"Activity being started in new voice task does not support: "
@@ -772,7 +772,7 @@
// launch the review activity and pass a pending intent to start the activity
// we are to launching now after the review is completed.
if (aInfo != null) {
- if (mService.mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
+ if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
IIntentSender target = mService.mAm.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage,
@@ -870,7 +870,7 @@
String resolvedType, int userId) {
if (auxiliaryResponse != null && auxiliaryResponse.needsPhaseTwo) {
// request phase two resolution
- mService.mAm.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
+ mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
auxiliaryResponse, originalIntent, resolvedType, callingPackage,
verificationBundle, userId);
}
@@ -970,7 +970,7 @@
&& !(Intent.ACTION_VIEW.equals(intent.getAction()) && intent.getData() == null)
&& !Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE.equals(intent.getAction())
&& !Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE.equals(intent.getAction())
- && mService.mAm.getPackageManagerInternalLocked()
+ && mService.getPackageManagerInternalLocked()
.isInstantAppInstallerComponent(intent.getComponent())) {
// intercept intents targeted directly to the ephemeral installer the
// ephemeral installer should never be started with a raw Intent; instead
@@ -1367,7 +1367,7 @@
// For paranoia, make sure we have correctly resumed the top activity.
topStack.mLastPausedActivity = null;
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
ActivityOptions.abort(mOptions);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
@@ -1451,7 +1451,7 @@
&& !mSupervisor.isTopDisplayFocusedStack(mTargetStack)) {
mTargetStack.moveToFront("startActivityUnchecked");
}
- mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked(mTargetStack, mStartActivity,
mOptions);
}
} else if (mStartActivity != null) {
@@ -2023,7 +2023,7 @@
private void resumeTargetStackIfNeeded() {
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, null, mOptions);
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked(mTargetStack, null, mOptions);
} else {
ActivityOptions.abort(mOptions);
}
@@ -2139,7 +2139,7 @@
// For paranoia, make sure we have correctly resumed the top activity.
mTargetStack.mLastPausedActivity = null;
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
ActivityOptions.abort(mOptions);
return START_DELIVERED_TO_TOP;
@@ -2157,7 +2157,7 @@
deliverNewIntent(top);
mTargetStack.mLastPausedActivity = null;
if (mDoResume) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
return START_DELIVERED_TO_TOP;
}
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index ab1ba6c..748b2d2 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.BIND_VOICE_INTERACTION;
import static android.Manifest.permission.CHANGE_CONFIGURATION;
import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
+import static android.Manifest.permission.FILTER_EVENTS;
import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
@@ -36,15 +37,12 @@
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.AppOpsManager.OP_NONE;
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
@@ -74,7 +72,6 @@
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
@@ -122,6 +119,8 @@
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver;
import android.os.IUserManager;
import android.os.PowerManager;
@@ -131,9 +130,9 @@
import android.os.WorkSource;
import android.view.WindowManager;
import com.android.internal.R;
-import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsService;
import com.android.server.AppOpsService;
+import com.android.server.SystemServiceManager;
import com.android.server.pm.UserManagerService;
import com.android.server.uri.UriGrantsManagerInternal;
import com.android.server.wm.ActivityTaskManagerInternal;
@@ -181,7 +180,6 @@
import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
-import android.os.Process;
import android.os.RemoteException;
import android.os.StrictMode;
import android.os.SystemClock;
@@ -250,6 +248,11 @@
private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
+ // How long we wait until we timeout on key dispatching.
+ private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
+ // How long we wait until we timeout on key dispatching during instrumentation.
+ private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
+
Context mContext;
/**
* This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
@@ -261,6 +264,7 @@
ActivityManagerService mAm;
ActivityManagerInternal mAmInternal;
UriGrantsManagerInternal mUgmInternal;
+ private PackageManagerInternal mPmInternal;
/* Global service lock used by the package the owns this service. */
Object mGlobalLock;
ActivityStackSupervisor mStackSupervisor;
@@ -269,6 +273,8 @@
private AppOpsService mAppOpsService;
/** All processes currently running that might have a window organized by name. */
final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
+ /** All processes we currently have running mapped by pid */
+ final SparseArray<WindowProcessController> mPidMap = new SparseArray<>();
/** This is the process holding what we currently consider to be the "home" activity. */
WindowProcessController mHomeProcess;
/**
@@ -466,6 +472,8 @@
/** If non-null, we are tracking the time the user spends in the currently focused app. */
AppTimeTracker mCurAppTimeTracker;
+ private AppWarnings mAppWarnings;
+
private FontScaleSettingObserver mFontScaleSettingObserver;
private final class FontScaleSettingObserver extends ContentObserver {
@@ -595,6 +603,8 @@
mGlobalLock = mAm;
mH = new H(mAm.mHandlerThread.getLooper());
mUiHandler = new UiHandler();
+ mAppWarnings = new AppWarnings(
+ this, mUiContext, mH, mUiHandler, SystemServiceManager.ensureSystemDir());
mTempConfig.setToDefaults();
mTempConfig.setLocales(LocaleList.getDefault());
@@ -1614,7 +1624,7 @@
final ActivityRecord r = stack.topRunningActivityLocked();
if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
r, "setFocusedStack")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
} finally {
@@ -1635,7 +1645,7 @@
}
final ActivityRecord r = task.topRunningActivityLocked();
if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
} finally {
@@ -2400,10 +2410,7 @@
public boolean isTopOfTask(IBinder token) {
synchronized (mGlobalLock) {
ActivityRecord r = ActivityRecord.isInStackLocked(token);
- if (r == null) {
- throw new IllegalArgumentException();
- }
- return r.getTask().getTopActivity() == r;
+ return r != null && r.getTask().getTopActivity() == r;
}
}
@@ -4008,7 +4015,7 @@
synchronized (mGlobalLock) {
final long origId = Binder.clearCallingIdentity();
try {
- mAm.mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
+ mAppWarnings.alwaysShowUnsupportedCompileSdkWarning(activity);
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -4493,7 +4500,7 @@
final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
if (isDensityChange && displayId == DEFAULT_DISPLAY) {
- mAm.mAppWarnings.onDensityChanged();
+ mAppWarnings.onDensityChanged();
mAm.killAllBackgroundProcessesExcept(N,
ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
@@ -4540,6 +4547,80 @@
&& mAmInternal.getCurrentUser().isDemo());
}
+ static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
+ if (r == null || !r.hasProcess()) {
+ return KEY_DISPATCHING_TIMEOUT_MS;
+ }
+ return getInputDispatchingTimeoutLocked(r.app);
+ }
+
+ private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
+ if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
+ return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
+ }
+ return KEY_DISPATCHING_TIMEOUT_MS;
+ }
+
+ long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
+ if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission " + FILTER_EVENTS);
+ }
+ WindowProcessController proc;
+ long timeout;
+ synchronized (mGlobalLock) {
+ proc = mPidMap.get(pid);
+ timeout = getInputDispatchingTimeoutLocked(proc);
+ }
+
+ if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
+ return -1;
+ }
+
+ return timeout;
+ }
+
+ /**
+ * Handle input dispatching timeouts.
+ * Returns whether input dispatching should be aborted or not.
+ */
+ boolean inputDispatchingTimedOut(final WindowProcessController proc,
+ final ActivityRecord activity, final ActivityRecord parent,
+ final boolean aboveSystem, String reason) {
+ if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission " + FILTER_EVENTS);
+ }
+
+ final String annotation;
+ if (reason == null) {
+ annotation = "Input dispatching timed out";
+ } else {
+ annotation = "Input dispatching timed out (" + reason + ")";
+ }
+
+ if (proc != null) {
+ synchronized (mGlobalLock) {
+ if (proc.isDebugging()) {
+ return false;
+ }
+
+ if (proc.isInstrumenting()) {
+ Bundle info = new Bundle();
+ info.putString("shortMsg", "keyDispatchingTimedOut");
+ info.putString("longMsg", annotation);
+ mAm.finishInstrumentationLocked(
+ (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
+ return true;
+ }
+ }
+ mH.post(() -> {
+ mAm.mAppErrors.appNotResponding(
+ (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
+ });
+ }
+
+ return true;
+ }
+
/**
* Decide based on the configuration whether we should show the ANR,
* crash, etc dialogs. The idea is that if there is no affordance to
@@ -4651,6 +4732,7 @@
updateResumedAppTrace(r);
mLastResumedActivity = r;
+ // TODO(b/111541062): Support multiple focused apps in WM
mWindowManager.setFocusedApp(r.appToken, true);
applyUpdateLockStateLocked(r);
@@ -4784,6 +4866,30 @@
return kept;
}
+ void scheduleAppGcsLocked() {
+ mH.post(() -> mAmInternal.scheduleAppGcs());
+ }
+
+ /**
+ * Returns the PackageManager. Used by classes hosted by {@link ActivityTaskManagerService}. The
+ * PackageManager could be unavailable at construction time and therefore needs to be accessed
+ * on demand.
+ */
+ IPackageManager getPackageManager() {
+ return AppGlobals.getPackageManager();
+ }
+
+ PackageManagerInternal getPackageManagerInternalLocked() {
+ if (mPmInternal == null) {
+ mPmInternal = LocalServices.getService(PackageManagerInternal.class);
+ }
+ return mPmInternal;
+ }
+
+ AppWarnings getAppWarningsLocked() {
+ return mAppWarnings;
+ }
+
void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
if (true || Build.IS_USER) {
return;
@@ -5041,7 +5147,7 @@
}
if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
r, "setFocusedActivity")) {
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
}
@@ -5232,5 +5338,41 @@
}
}
}
+
+ @Override
+ public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
+ synchronized (mGlobalLock) {
+ return ActivityTaskManagerService.this.inputDispatchingTimedOut(
+ pid, aboveSystem, reason);
+ }
+ }
+
+ @Override
+ public void onProcessMapped(int pid, WindowProcessController proc) {
+ synchronized (mGlobalLock) {
+ mPidMap.put(pid, proc);
+ }
+ }
+
+ @Override
+ public void onProcessUnMapped(int pid) {
+ synchronized (mGlobalLock) {
+ mPidMap.remove(pid);
+ }
+ }
+
+ @Override
+ public void onPackageDataCleared(String name) {
+ synchronized (mGlobalLock) {
+ mAppWarnings.onPackageDataCleared(name);
+ }
+ }
+
+ @Override
+ public void onPackageUninstalled(String name) {
+ synchronized (mGlobalLock) {
+ mAppWarnings.onPackageUninstalled(name);
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 7652dd4..3b98f37 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -436,7 +436,7 @@
* If this process was running instrumentation, finish now - it will be handled in
* {@link ActivityManagerService#handleAppDiedLocked}.
*/
- if (r != null && r.instr != null) {
+ if (r != null && r.getActiveInstrumentation() != null) {
return;
}
@@ -503,7 +503,7 @@
mService.mStackSupervisor.handleAppCrashLocked(r.getWindowProcessController());
if (!r.isPersistent()) {
mService.removeProcessLocked(r, false, false, "crash");
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
} finally {
Binder.restoreCallingIdentity(orig);
@@ -743,12 +743,12 @@
// annoy the user repeatedly. Unless it is persistent, since those
// processes run critical code.
mService.removeProcessLocked(app, false, tryAgain, "crash");
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
if (!showBackground) {
return false;
}
}
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
} else {
final TaskRecord affectedTask =
mService.mStackSupervisor.finishTopCrashedActivitiesLocked(app.getWindowProcessController(), reason);
diff --git a/services/core/java/com/android/server/am/AppWarnings.java b/services/core/java/com/android/server/am/AppWarnings.java
index 30a3844..a705180 100644
--- a/services/core/java/com/android/server/am/AppWarnings.java
+++ b/services/core/java/com/android/server/am/AppWarnings.java
@@ -17,7 +17,6 @@
package com.android.server.am;
import android.annotation.UiThread;
-import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
@@ -57,9 +56,9 @@
private final HashMap<String, Integer> mPackageFlags = new HashMap<>();
- private final ActivityManagerService mAms;
+ private final ActivityTaskManagerService mAtm;
private final Context mUiContext;
- private final ConfigHandler mAmsHandler;
+ private final ConfigHandler mHandler;
private final UiHandler mUiHandler;
private final AtomicFile mConfigFile;
@@ -81,17 +80,17 @@
* <p>
* <strong>Note:</strong> Must be called from the ActivityManagerService thread.
*
- * @param ams
+ * @param atm
* @param uiContext
- * @param amsHandler
+ * @param handler
* @param uiHandler
* @param systemDir
*/
- public AppWarnings(ActivityManagerService ams, Context uiContext, Handler amsHandler,
+ public AppWarnings(ActivityTaskManagerService atm, Context uiContext, Handler handler,
Handler uiHandler, File systemDir) {
- mAms = ams;
+ mAtm = atm;
mUiContext = uiContext;
- mAmsHandler = new ConfigHandler(amsHandler.getLooper());
+ mHandler = new ConfigHandler(handler.getLooper());
mUiHandler = new UiHandler(uiHandler.getLooper());
mConfigFile = new AtomicFile(new File(systemDir, CONFIG_FILE_NAME), "warnings-config");
@@ -104,7 +103,7 @@
* @param r activity record for which the warning may be displayed
*/
public void showUnsupportedDisplaySizeDialogIfNeeded(ActivityRecord r) {
- final Configuration globalConfig = mAms.getGlobalConfiguration();
+ final Configuration globalConfig = mAtm.getGlobalConfiguration();
if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
&& r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
mUiHandler.showUnsupportedDisplaySizeDialog(r);
@@ -211,7 +210,7 @@
synchronized (mPackageFlags) {
mPackageFlags.remove(name);
- mAmsHandler.scheduleWrite();
+ mHandler.scheduleWrite();
}
}
@@ -351,7 +350,7 @@
} else {
mPackageFlags.remove(name);
}
- mAmsHandler.scheduleWrite();
+ mHandler.scheduleWrite();
}
}
}
@@ -430,10 +429,10 @@
}
/**
- * Handles messages on the ActivityManagerService thread.
+ * Handles messages on the ActivityTaskManagerService thread.
*/
private final class ConfigHandler extends Handler {
- private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG;
+ private static final int MSG_WRITE = 1;
private static final int DELAY_MSG_WRITE = 10000;
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 046cfc7..b36b5d3 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1462,7 +1462,7 @@
// If the receiver app is being debugged we quietly ignore unresponsiveness, just
// tidying up and moving on to the next broadcast without crashing or ANRing this
// app just because it's stopped at a breakpoint.
- final boolean debugging = (r.curApp != null && r.curApp.debugging);
+ final boolean debugging = (r.curApp != null && r.curApp.isDebugging());
Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
+ ", started " + (now - r.receiverTime) + "ms ago");
diff --git a/services/core/java/com/android/server/am/CompatModeDialog.java b/services/core/java/com/android/server/am/CompatModeDialog.java
deleted file mode 100644
index 202cc7c..0000000
--- a/services/core/java/com/android/server/am/CompatModeDialog.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 com.android.server.am;
-
-import android.app.ActivityManager;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.view.Gravity;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.Switch;
-
-public final class CompatModeDialog extends Dialog {
- final ActivityManagerService mService;
- final ApplicationInfo mAppInfo;
-
- final Switch mCompatEnabled;
- final CheckBox mAlwaysShow;
- final View mHint;
-
- public CompatModeDialog(ActivityManagerService service, Context context,
- ApplicationInfo appInfo) {
- super(context, com.android.internal.R.style.Theme_Holo_Dialog_MinWidth);
- setCancelable(true);
- setCanceledOnTouchOutside(true);
- getWindow().requestFeature(Window.FEATURE_NO_TITLE);
- getWindow().setType(WindowManager.LayoutParams.TYPE_PHONE);
- getWindow().setGravity(Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL);
- mService = service;
- mAppInfo = appInfo;
-
- setContentView(com.android.internal.R.layout.am_compat_mode_dialog);
- mCompatEnabled = (Switch)findViewById(com.android.internal.R.id.compat_checkbox);
- mCompatEnabled.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- synchronized (mService) {
- mService.mCompatModePackages.setPackageScreenCompatModeLocked(
- mAppInfo.packageName,
- mCompatEnabled.isChecked() ? ActivityManager.COMPAT_MODE_ENABLED
- : ActivityManager.COMPAT_MODE_DISABLED);
- updateControls();
- }
- }
- });
- mAlwaysShow = (CheckBox)findViewById(com.android.internal.R.id.ask_checkbox);
- mAlwaysShow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- synchronized (mService) {
- mService.mCompatModePackages.setPackageAskCompatModeLocked(
- mAppInfo.packageName, mAlwaysShow.isChecked());
- updateControls();
- }
- }
- });
- mHint = findViewById(com.android.internal.R.id.reask_hint);
-
- updateControls();
- }
-
- void updateControls() {
- synchronized (mService) {
- int mode = mService.mCompatModePackages.computeCompatModeLocked(mAppInfo);
- mCompatEnabled.setChecked(mode == ActivityManager.COMPAT_MODE_ENABLED);
- boolean ask = mService.mCompatModePackages.getPackageAskCompatModeLocked(
- mAppInfo.packageName);
- mAlwaysShow.setChecked(ask);
- mHint.setVisibility(ask ? View.INVISIBLE : View.VISIBLE);
- }
- }
-}
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index e345b4d..ee4e36f 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -163,7 +163,7 @@
updateKeyguardSleepToken();
// Some stack visibility might change (e.g. docked stack)
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mStackSupervisor.addStartingWindowsForVisibleActivities(true /* taskSwitch */);
mWindowManager.executeAppTransition();
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index 4fd01cd..643c922 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -446,7 +446,7 @@
return;
}
task.performClearTaskLocked();
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
/**
@@ -578,7 +578,7 @@
if (andResume) {
mSupervisor.findTaskToMoveToFront(task, 0, null, reason,
lockTaskModeState != LOCK_TASK_MODE_NONE);
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
mWindowManager.executeAppTransition();
} else if (lockTaskModeState != LOCK_TASK_MODE_NONE) {
mSupervisor.handleNonResizableTaskIfNeeded(task, WINDOWING_MODE_UNDEFINED,
@@ -653,7 +653,7 @@
}
if (taskChanged) {
- mSupervisor.resumeFocusedStackTopActivityLocked();
+ mSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index b33ce2b..8c552b9 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -187,8 +187,9 @@
int lruSeq; // Sequence id for identifying LRU update cycles
CompatibilityInfo compat; // last used compatibility mode
IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
- ActiveInstrumentation instr;// Set to currently active instrumentation running in process
- boolean usingWrapper; // Set to true when process was launched with a wrapper attached
+ private ActiveInstrumentation mInstr; // Set to currently active instrumentation running in
+ // process.
+ private boolean mUsingWrapper; // Set to true when process was launched with a wrapper attached
final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
long whenUnimportant; // When (uptime) the process last became unimportant
long lastCpuTime; // How long proc has run CPU at last check
@@ -232,7 +233,7 @@
private boolean mNotResponding; // does the app have a not responding dialog?
Dialog anrDialog; // dialog being displayed due to app not resp.
boolean removed; // has app package been removed from device?
- boolean debugging; // was app launched for debugging?
+ private boolean mDebugging; // was app launched for debugging?
boolean waitedForDebugger; // has process show wait for debugger dialog?
Dialog waitDialog; // current wait for debugger dialog
@@ -317,8 +318,8 @@
pw.println("}");
}
pw.print(prefix); pw.print("compat="); pw.println(compat);
- if (instr != null) {
- pw.print(prefix); pw.print("instr="); pw.println(instr);
+ if (mInstr != null) {
+ pw.print(prefix); pw.print("mInstr="); pw.println(mInstr);
}
pw.print(prefix); pw.print("thread="); pw.println(thread);
pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
@@ -435,9 +436,9 @@
pw.print(" killedByAm="); pw.print(killedByAm);
pw.print(" waitingToKill="); pw.println(waitingToKill);
}
- if (debugging || mCrashing || crashDialog != null || mNotResponding
+ if (mDebugging || mCrashing || crashDialog != null || mNotResponding
|| anrDialog != null || bad) {
- pw.print(prefix); pw.print("debugging="); pw.print(debugging);
+ pw.print(prefix); pw.print("mDebugging="); pw.print(mDebugging);
pw.print(" mCrashing="); pw.print(mCrashing);
pw.print(" "); pw.print(crashDialog);
pw.print(" mNotResponding="); pw.print(mNotResponding);
@@ -975,6 +976,33 @@
return mHasForegroundServices;
}
+ void setDebugging(boolean debugging) {
+ mDebugging = debugging;
+ mWindowProcessController.setDebugging(debugging);
+ }
+
+ boolean isDebugging() {
+ return mDebugging;
+ }
+
+ void setUsingWrapper(boolean usingWrapper) {
+ mUsingWrapper = usingWrapper;
+ mWindowProcessController.setUsingWrapper(usingWrapper);
+ }
+
+ boolean isUsingWrapper() {
+ return mUsingWrapper;
+ }
+
+ void setActiveInstrumentation(ActiveInstrumentation instr) {
+ mInstr = instr;
+ mWindowProcessController.setInstrumenting(instr != null);
+ }
+
+ ActiveInstrumentation getActiveInstrumentation() {
+ return mInstr;
+ }
+
@Override
public void clearProfilerIfNeeded() {
synchronized (mService) {
diff --git a/services/core/java/com/android/server/am/ProcessStatsService.java b/services/core/java/com/android/server/am/ProcessStatsService.java
index f0bd8fa..8ce650c 100644
--- a/services/core/java/com/android/server/am/ProcessStatsService.java
+++ b/services/core/java/com/android/server/am/ProcessStatsService.java
@@ -612,7 +612,8 @@
stats.dumpCheckinLocked(pw, reqPackage);
} else {
if (dumpDetails || dumpFullDetails) {
- stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll, activeOnly);
+ stats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails, dumpAll,
+ activeOnly);
} else {
stats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
}
@@ -974,8 +975,8 @@
if (checkedIn) pw.print(" (checked in)");
pw.println(":");
if (dumpDetails || dumpFullDetails) {
- processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll,
- activeOnly);
+ processStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
+ dumpAll, activeOnly);
if (dumpAll) {
pw.print(" mFile="); pw.println(mFile.getBaseFile());
}
@@ -1030,7 +1031,7 @@
// much crud.
if (dumpFullDetails) {
processStats.dumpLocked(pw, reqPackage, now, false, false,
- activeOnly);
+ false, activeOnly);
} else {
processStats.dumpSummaryLocked(pw, reqPackage, now, activeOnly);
}
@@ -1060,8 +1061,8 @@
}
pw.println("CURRENT STATS:");
if (dumpDetails || dumpFullDetails) {
- mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpAll,
- activeOnly);
+ mProcessStats.dumpLocked(pw, reqPackage, now, !dumpFullDetails, dumpDetails,
+ dumpAll, activeOnly);
if (dumpAll) {
pw.print(" mFile="); pw.println(mFile.getBaseFile());
}
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 230810b..fb6b5c1 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -288,7 +288,7 @@
* @return whether the home app is also the active handler of recent tasks.
*/
boolean isRecentsComponentHomeActivity(int userId) {
- final ComponentName defaultHomeActivity = mService.mAm.getPackageManagerInternalLocked()
+ final ComponentName defaultHomeActivity = mService.getPackageManagerInternalLocked()
.getDefaultHomeActivity(userId);
return defaultHomeActivity != null && mRecentsComponent != null &&
defaultHomeActivity.getPackageName().equals(mRecentsComponent.getPackageName());
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index 1c7ad3f..c5586bb 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -287,7 +287,7 @@
mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, false);
- mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
// No reason to wait for the pausing activity in this case, as the hiding of
// surfaces needs to be done immediately.
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 2d0c2a8..7256e23 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -16,9 +16,9 @@
package com.android.server.am;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
-import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
@@ -63,6 +63,7 @@
import static com.android.server.am.ActivityStackSupervisor.PAUSE_IMMEDIATELY;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.am.TaskRecordProto.ACTIVITIES;
+import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
import static com.android.server.am.TaskRecordProto.BOUNDS;
import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.TaskRecordProto.FULLSCREEN;
@@ -74,7 +75,6 @@
import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
import static com.android.server.am.TaskRecordProto.STACK_ID;
-import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
import static java.lang.Integer.MAX_VALUE;
@@ -87,7 +87,6 @@
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
import android.app.AppGlobals;
-import android.app.IActivityManager;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Intent;
@@ -478,7 +477,7 @@
mResizeMode = resizeMode;
mWindowContainerController.setResizeable(resizeMode);
mService.mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
void setTaskDockedResizing(boolean resizing) {
@@ -552,7 +551,7 @@
mService.mStackSupervisor.ensureActivitiesVisibleLocked(r, 0,
preserveWindow);
if (!kept) {
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
}
@@ -752,7 +751,7 @@
// The task might have already been running and its visibility needs to be synchronized
// with the visibility of the stack / windows.
supervisor.ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow);
- supervisor.resumeFocusedStackTopActivityLocked();
+ supervisor.resumeFocusedStacksTopActivitiesLocked();
}
// TODO: Handle incorrect request to move before the actual move, not after.
@@ -1748,6 +1747,14 @@
return updateOverrideConfiguration(bounds, null /* insetBounds */);
}
+ void setLastNonFullscreenBounds(Rect bounds) {
+ if (mLastNonFullscreenBounds == null) {
+ mLastNonFullscreenBounds = new Rect(bounds);
+ } else {
+ mLastNonFullscreenBounds.set(bounds);
+ }
+ }
+
/**
* Update task's override configuration based on the bounds.
* @param bounds The bounds of the task.
@@ -1769,7 +1776,7 @@
final boolean persistBounds = getWindowConfiguration().persistTaskBounds();
if (matchParentBounds) {
if (!currentBounds.isEmpty() && persistBounds) {
- mLastNonFullscreenBounds = currentBounds;
+ setLastNonFullscreenBounds(currentBounds);
}
setBounds(null);
newConfig.unset();
@@ -1779,7 +1786,7 @@
setBounds(mTmpRect);
if (mStack == null || persistBounds) {
- mLastNonFullscreenBounds = getOverrideBounds();
+ setLastNonFullscreenBounds(getOverrideBounds());
}
computeOverrideConfiguration(newConfig, mTmpRect, insetBounds,
mTmpRect.right != bounds.right, mTmpRect.bottom != bounds.bottom);
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index ba604e0..f854df6 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -104,11 +104,9 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -2243,7 +2241,7 @@
protected void stackSupervisorResumeFocusedStackTopActivity() {
synchronized (mService) {
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
}
}
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index d4c9bcb..e5551b5 100644
--- a/services/core/java/com/android/server/am/WindowProcessController.java
+++ b/services/core/java/com/android/server/am/WindowProcessController.java
@@ -93,6 +93,12 @@
private volatile String mRequiredAbi;
// Running any services that are foreground?
private volatile boolean mHasForegroundServices;
+ // was app launched for debugging?
+ private volatile boolean mDebugging;
+ // Active instrumentation running in process?
+ private volatile boolean mInstrumenting;
+ // Set to true when process was launched with a wrapper attached
+ private volatile boolean mUsingWrapper;
// Thread currently set for VR scheduling
int mVrThreadTid;
@@ -189,6 +195,30 @@
return mRequiredAbi;
}
+ public void setDebugging(boolean debugging) {
+ mDebugging = debugging;
+ }
+
+ boolean isDebugging() {
+ return mDebugging;
+ }
+
+ public void setUsingWrapper(boolean usingWrapper) {
+ mUsingWrapper = usingWrapper;
+ }
+
+ boolean isUsingWrapper() {
+ return mUsingWrapper;
+ }
+
+ public void setInstrumenting(boolean instrumenting) {
+ mInstrumenting = instrumenting;
+ }
+
+ boolean isInstrumenting() {
+ return mInstrumenting;
+ }
+
public void addPackage(String packageName) {
synchronized (mAtm.mGlobalLock) {
mPkgList.add(packageName);
diff --git a/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java
index 02cc6d5..10a1b90 100644
--- a/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/common/AuthenticationClient.java
@@ -114,7 +114,7 @@
if (mBundle != null) {
try {
if (acquiredInfo != BiometricConstants.BIOMETRIC_ACQUIRED_GOOD) {
- mStatusBarService.onFingerprintHelp(
+ mStatusBarService.onBiometricHelp(
mFingerprintManager.getAcquiredString(acquiredInfo, vendorCode));
}
return false; // acquisition continues
@@ -143,7 +143,7 @@
}
if (mBundle != null) {
try {
- mStatusBarService.onFingerprintError(
+ mStatusBarService.onBiometricError(
mFingerprintManager.getErrorString(error, vendorCode));
} catch (RemoteException e) {
Slog.e(getLogTag(), "Remote exception when sending error", e);
@@ -162,9 +162,9 @@
if (mBundle != null) {
try {
if (authenticated) {
- mStatusBarService.onFingerprintAuthenticated();
+ mStatusBarService.onBiometricAuthenticated();
} else {
- mStatusBarService.onFingerprintHelp(getContext().getResources().getString(
+ mStatusBarService.onBiometricHelp(getContext().getResources().getString(
com.android.internal.R.string.fingerprint_not_recognized));
}
} catch (RemoteException e) {
@@ -224,7 +224,7 @@
// Send the lockout message to the system dialog
if (mBundle != null) {
- mStatusBarService.onFingerprintError(
+ mStatusBarService.onBiometricError(
mFingerprintManager.getErrorString(errorCode, 0 /* vendorCode */));
}
} catch (RemoteException e) {
@@ -263,7 +263,7 @@
// If authenticating with system dialog, show the dialog
if (mBundle != null) {
try {
- mStatusBarService.showFingerprintDialog(mBundle, mDialogReceiver);
+ mStatusBarService.showBiometricDialog(mBundle, mDialogReceiver);
} catch (RemoteException e) {
Slog.e(getLogTag(), "Unable to show fingerprint dialog", e);
}
@@ -301,7 +301,7 @@
// after BiometricPrompt.HIDE_DIALOG_DELAY
if (mBundle != null && !mDialogDismissed && !mInLockout) {
try {
- mStatusBarService.hideFingerprintDialog();
+ mStatusBarService.hideBiometricDialog();
} catch (RemoteException e) {
Slog.e(getLogTag(), "Unable to hide fingerprint dialog", e);
}
diff --git a/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java
new file mode 100644
index 0000000..7e73321
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/ArcTerminationActionFromAvr.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.hdmi;
+
+import android.hardware.tv.cec.V1_0.SendMessageResult;
+
+/**
+ * Feature action that handles Audio Return Channel terminated by AVR devices.
+ */
+public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction {
+
+ // State in which waits for ARC response.
+ private static final int STATE_WAITING_FOR_INITIATE_ARC_RESPONSE = 1;
+ private static final int STATE_ARC_TERMINATED = 2;
+
+ // the required maximum response time specified in CEC 9.2
+ private static final int TIMEOUT_MS = 1000;
+
+ ArcTerminationActionFromAvr(HdmiCecLocalDevice source) {
+ super(source);
+ }
+
+ @Override
+ boolean start() {
+ mState = STATE_WAITING_FOR_INITIATE_ARC_RESPONSE;
+ addTimer(mState, TIMEOUT_MS);
+ sendTerminateArc();
+ return true;
+ }
+
+ @Override
+ boolean processCommand(HdmiCecMessage cmd) {
+ if (mState != STATE_WAITING_FOR_INITIATE_ARC_RESPONSE) {
+ return false;
+ }
+ switch (cmd.getOpcode()) {
+ case Constants.MESSAGE_REPORT_ARC_TERMINATED:
+ mState = STATE_ARC_TERMINATED;
+ audioSystem().setArcStatus(false);
+ finish();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ void handleTimerEvent(int state) {
+ if (mState != state) {
+ return;
+ }
+
+ switch (mState) {
+ case STATE_WAITING_FOR_INITIATE_ARC_RESPONSE:
+ handleTerminateArcTimeout();
+ break;
+ }
+ }
+
+ protected void sendTerminateArc() {
+ sendCommand(HdmiCecMessageBuilder.buildTerminateArc(getSourceAddress(), Constants.ADDR_TV),
+ result -> {
+ if (result != SendMessageResult.SUCCESS) {
+ HdmiLogger.debug("Terminate ARC was not successfully sent.");
+ finish();
+ }
+ });
+ }
+
+ private void handleTerminateArcTimeout() {
+ HdmiLogger.debug("handleTerminateArcTimeout");
+ finish();
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java
index ba5ee02..d154830 100644
--- a/services/core/java/com/android/server/hdmi/Constants.java
+++ b/services/core/java/com/android/server/hdmi/Constants.java
@@ -295,6 +295,13 @@
"persist.sys.hdmi.last_system_audio_control";
/**
+ * Property to indicate if device supports ARC or not
+ * <p>Default is true.
+ */
+ static final String PROPERTY_ARC_SUPPORT =
+ "persist.sys.hdmi.property_arc_support";
+
+ /**
* Property to save the audio port to switch to when system audio control is on.
* <P>Audio system should switch to this port when cec active source is not its child in the tree
* or is not itself.
@@ -311,6 +318,17 @@
static final String PROPERTY_SYSTEM_AUDIO_DEVICE_ARC_PORT =
"persist.sys.hdmi.property_sytem_audio_device_arc_port";
+ /**
+ * Property to strip local audio of amplifier and use local speaker
+ * when TV does not support system audio mode.
+ *
+ * <p>This property applies to device with both audio system/playback types.
+ * <p>True means using local speaker when TV does not support system audio.
+ * <p>False means passing audio to TV. Default is true.
+ */
+ static final String PROPERTY_STRIP_AUDIO_TV_NO_SYSTEM_AUDIO =
+ "persist.sys.hdmi.property_strip_audio_tv_no_system_audio";
+
static final int RECORDING_TYPE_DIGITAL_RF = 1;
static final int RECORDING_TYPE_ANALOGUE_RF = 2;
static final int RECORDING_TYPE_EXTERNAL_PHYSICAL_ADDRESS = 3;
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 7aab750..14af15f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -189,15 +189,14 @@
@ServiceThreadOnly
protected boolean handleRequestArcInitiate(HdmiCecMessage message) {
assertRunOnServiceThread();
- // TODO(b/80296911): Check if ARC supported.
-
- // TODO(b/80296911): Check if port is ready to accept.
-
- // TODO(b/80296911): if both true, activate ARC functinality and
- mService.sendCecCommand(
- HdmiCecMessageBuilder.buildInitiateArc(mAddress, message.getSource()));
- // TODO(b/80296911): else, send <Feature Abort>["Unrecongnized opcode"]
-
+ if (!SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) {
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+ } else if (!isDirectConnectToTv()) {
+ HdmiLogger.debug("AVR device is not directly connected with TV");
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+ } else {
+ addAndStartAction(new ArcInitiationActionFromAvr(this));
+ }
return true;
}
@@ -205,15 +204,14 @@
@ServiceThreadOnly
protected boolean handleRequestArcTermination(HdmiCecMessage message) {
assertRunOnServiceThread();
- // TODO(b/80297105): Check if ARC supported.
-
- // TODO(b/80297105): Check is currently in arc.
-
- // TODO(b/80297105): If both true, deactivate ARC functionality and
- mService.sendCecCommand(
- HdmiCecMessageBuilder.buildTerminateArc(mAddress, message.getSource()));
- // TODO(b/80297105): else, send <Feature Abort>["Unrecongnized opcode"]
-
+ if (!SystemProperties.getBoolean(Constants.PROPERTY_ARC_SUPPORT, true)) {
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_UNRECOGNIZED_OPCODE);
+ } else if (!isArcEnabled()) {
+ HdmiLogger.debug("ARC is not established between TV and AVR device");
+ mService.maySendFeatureAbortCommand(message, Constants.ABORT_NOT_IN_CORRECT_MODE);
+ } else {
+ addAndStartAction(new ArcTerminationActionFromAvr(this));
+ }
return true;
}
@@ -329,18 +327,7 @@
!isPhysicalAddressMeOrBelow(targetPhysicalAddress)) {
switchToAudioInput();
}
- // Mute device when feature is turned off and unmute device when feature is turned on
- boolean currentMuteStatus =
- mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC);
- if (currentMuteStatus == newSystemAudioMode) {
- mService.getAudioManager()
- .adjustStreamVolume(
- AudioManager.STREAM_MUSIC,
- newSystemAudioMode
- ? AudioManager.ADJUST_UNMUTE
- : AudioManager.ADJUST_MUTE,
- 0);
- }
+ // TODO(b/80297700): Mute device when TV terminates the system audio control
updateAudioManagerForSystemAudio(newSystemAudioMode);
synchronized (mLock) {
if (mSystemAudioActivated != newSystemAudioMode) {
@@ -377,6 +364,11 @@
// TODO(b/111396634): switch input according to PROPERTY_SYSTEM_AUDIO_MODE_AUDIO_PORT
}
+ protected boolean isDirectConnectToTv() {
+ int myPhysicalAddress = mService.getPhysicalAddress();
+ return (myPhysicalAddress & Constants.ROUTING_PATH_TOP_MASK) == myPhysicalAddress;
+ }
+
private void updateAudioManagerForSystemAudio(boolean on) {
int device = mService.getAudioManager().setHdmiSystemAudioSupported(on);
HdmiLogger.debug("[A]UpdateSystemAudio mode[on=%b] output=[%X]", on, device);
@@ -435,4 +427,11 @@
void setTvSystemAudioModeSupport(boolean supported) {
mTvSystemAudioModeSupport = supported;
}
+
+ @VisibleForTesting
+ protected boolean isArcEnabled() {
+ synchronized (mLock) {
+ return mArcEstablished;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
index f1cb246..649a2da 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
@@ -18,6 +18,7 @@
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
+import com.android.server.hdmi.Constants.AudioCodec;
/**
* A helper class to build {@link HdmiCecMessage} from various cec commands.
@@ -265,6 +266,25 @@
return buildCommand(src, dest, Constants.MESSAGE_REPORT_ARC_TERMINATED);
}
+
+ /**
+ * Build <Request Short Audio Descriptor> command.
+ *
+ * @param src source address of command
+ * @param dest destination address of command
+ * @param audioFormats the {@link AudioCodec}s desired
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage buildRequestShortAudioDescriptor(int src, int dest,
+ @AudioCodec int[] audioFormats) {
+ byte[] params = new byte[Math.min(audioFormats.length,4)] ;
+ for (int i = 0; i < params.length ; i++){
+ params[i] = (byte) (audioFormats[i] & 0xff);
+ }
+ return buildCommand(src, dest, Constants.MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR, params);
+ }
+
+
/**
* Build <Text View On> command.
*
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 644f2c4..e3c311f 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -16,41 +16,33 @@
package com.android.server.job.controllers;
-import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
-
-import android.app.AlarmManager;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.os.UserHandle;
import android.util.ArraySet;
-import android.util.Log;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.am.ActivityManagerService;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateControllerProto;
+import com.android.server.job.controllers.idle.CarIdlenessTracker;
+import com.android.server.job.controllers.idle.DeviceIdlenessTracker;
+import com.android.server.job.controllers.idle.IdlenessListener;
+import com.android.server.job.controllers.idle.IdlenessTracker;
import java.util.function.Predicate;
-public final class IdleController extends StateController {
- private static final String TAG = "JobScheduler.Idle";
- private static final boolean DEBUG = JobSchedulerService.DEBUG
- || Log.isLoggable(TAG, Log.DEBUG);
-
+public final class IdleController extends StateController implements IdlenessListener {
+ private static final String TAG = "JobScheduler.IdleController";
// Policy: we decide that we're "idle" if the device has been unused /
// screen off or dreaming or wireless charging dock idle for at least this long
- private long mInactivityIdleThreshold;
- private long mIdleWindowSlop;
final ArraySet<JobStatus> mTrackedTasks = new ArraySet<>();
IdlenessTracker mIdleTracker;
public IdleController(JobSchedulerService service) {
super(service);
- initIdleStateTracking();
+ initIdleStateTracking(mContext);
}
/**
@@ -74,9 +66,10 @@
}
/**
- * Interaction with the task manager service
+ * State-change notifications from the idleness tracker
*/
- void reportNewIdleState(boolean isIdle) {
+ @Override
+ public void reportNewIdleState(boolean isIdle) {
synchronized (mLock) {
for (int i = mTrackedTasks.size()-1; i >= 0; i--) {
mTrackedTasks.valueAt(i).setIdleConstraintSatisfied(isIdle);
@@ -89,141 +82,22 @@
* Idle state tracking, and messaging with the task manager when
* significant state changes occur
*/
- private void initIdleStateTracking() {
- mInactivityIdleThreshold = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_jobSchedulerInactivityIdleThreshold);
- mIdleWindowSlop = mContext.getResources().getInteger(
- com.android.internal.R.integer.config_jobSchedulerIdleWindowSlop);
- mIdleTracker = new IdlenessTracker();
- mIdleTracker.startTracking();
- }
-
- final class IdlenessTracker extends BroadcastReceiver {
- private AlarmManager mAlarm;
-
- // After construction, mutations of idle/screen-on state will only happen
- // on the main looper thread, either in onReceive() or in an alarm callback.
- private boolean mIdle;
- private boolean mScreenOn;
- private boolean mDockIdle;
-
- private AlarmManager.OnAlarmListener mIdleAlarmListener = () -> {
- handleIdleTrigger();
- };
-
- public IdlenessTracker() {
- mAlarm = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
-
- // At boot we presume that the user has just "interacted" with the
- // device in some meaningful way.
- mIdle = false;
- mScreenOn = true;
- mDockIdle = false;
+ private void initIdleStateTracking(Context ctx) {
+ final boolean isCar = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE);
+ if (isCar) {
+ mIdleTracker = new CarIdlenessTracker();
+ } else {
+ mIdleTracker = new DeviceIdlenessTracker();
}
-
- public boolean isIdle() {
- return mIdle;
- }
-
- public void startTracking() {
- IntentFilter filter = new IntentFilter();
-
- // Screen state
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
-
- // Dreaming state
- filter.addAction(Intent.ACTION_DREAMING_STARTED);
- filter.addAction(Intent.ACTION_DREAMING_STOPPED);
-
- // Debugging/instrumentation
- filter.addAction(ActivityManagerService.ACTION_TRIGGER_IDLE);
-
- // Wireless charging dock state
- filter.addAction(Intent.ACTION_DOCK_IDLE);
- filter.addAction(Intent.ACTION_DOCK_ACTIVE);
-
- mContext.registerReceiver(this, filter);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (action.equals(Intent.ACTION_SCREEN_ON)
- || action.equals(Intent.ACTION_DREAMING_STOPPED)
- || action.equals(Intent.ACTION_DOCK_ACTIVE)) {
- if (action.equals(Intent.ACTION_DOCK_ACTIVE)) {
- if (!mScreenOn) {
- // Ignore this intent during screen off
- return;
- } else {
- mDockIdle = false;
- }
- } else {
- mScreenOn = true;
- mDockIdle = false;
- }
- if (DEBUG) {
- Slog.v(TAG,"exiting idle : " + action);
- }
- //cancel the alarm
- mAlarm.cancel(mIdleAlarmListener);
- if (mIdle) {
- // possible transition to not-idle
- mIdle = false;
- reportNewIdleState(mIdle);
- }
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)
- || action.equals(Intent.ACTION_DREAMING_STARTED)
- || action.equals(Intent.ACTION_DOCK_IDLE)) {
- // when the screen goes off or dreaming starts or wireless charging dock in idle,
- // we schedule the alarm that will tell us when we have decided the device is
- // truly idle.
- if (action.equals(Intent.ACTION_DOCK_IDLE)) {
- if (!mScreenOn) {
- // Ignore this intent during screen off
- return;
- } else {
- mDockIdle = true;
- }
- } else {
- mScreenOn = false;
- mDockIdle = false;
- }
- final long nowElapsed = sElapsedRealtimeClock.millis();
- final long when = nowElapsed + mInactivityIdleThreshold;
- if (DEBUG) {
- Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
- + when);
- }
- mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
- when, mIdleWindowSlop, "JS idleness", mIdleAlarmListener, null);
- } else if (action.equals(ActivityManagerService.ACTION_TRIGGER_IDLE)) {
- handleIdleTrigger();
- }
- }
-
- private void handleIdleTrigger() {
- // idle time starts now. Do not set mIdle if screen is on.
- if (!mIdle && (!mScreenOn || mDockIdle)) {
- if (DEBUG) {
- Slog.v(TAG, "Idle trigger fired @ " + sElapsedRealtimeClock.millis());
- }
- mIdle = true;
- reportNewIdleState(mIdle);
- } else {
- if (DEBUG) {
- Slog.v(TAG, "TRIGGER_IDLE received but not changing state; idle="
- + mIdle + " screen=" + mScreenOn);
- }
- }
- }
+ mIdleTracker.startTracking(ctx, this);
}
@Override
public void dumpControllerStateLocked(IndentingPrintWriter pw,
Predicate<JobStatus> predicate) {
pw.println("Currently idle: " + mIdleTracker.isIdle());
+ pw.println("Idleness tracker:"); mIdleTracker.dump(pw);
pw.println();
for (int i = 0; i < mTrackedTasks.size(); i++) {
diff --git a/services/core/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java b/services/core/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java
new file mode 100644
index 0000000..596a4c0
--- /dev/null
+++ b/services/core/java/com/android/server/job/controllers/idle/CarIdlenessTracker.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job.controllers.idle;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import android.util.Log;
+import android.util.Slog;
+import com.android.server.am.ActivityManagerService;
+import com.android.server.job.JobSchedulerService;
+
+import java.io.PrintWriter;
+
+public final class CarIdlenessTracker extends BroadcastReceiver implements IdlenessTracker {
+ private static final String TAG = "JobScheduler.CarIdlenessTracker";
+ private static final boolean DEBUG = JobSchedulerService.DEBUG
+ || Log.isLoggable(TAG, Log.DEBUG);
+
+ public static final String ACTION_GARAGE_MODE_ON =
+ "com.android.server.jobscheduler.GARAGE_MODE_ON";
+ public static final String ACTION_GARAGE_MODE_OFF =
+ "com.android.server.jobscheduler.GARAGE_MODE_OFF";
+
+ public static final String ACTION_FORCE_IDLE = "com.android.server.jobscheduler.FORCE_IDLE";
+ public static final String ACTION_UNFORCE_IDLE = "com.android.server.jobscheduler.UNFORCE_IDLE";
+
+ // After construction, mutations of idle/screen-on state will only happen
+ // on the main looper thread, either in onReceive() or in an alarm callback.
+ private boolean mIdle;
+ private boolean mGarageModeOn;
+ private boolean mForced;
+ private IdlenessListener mIdleListener;
+
+ public CarIdlenessTracker() {
+ // At boot we presume that the user has just "interacted" with the
+ // device in some meaningful way.
+ mIdle = false;
+ mGarageModeOn = false;
+ mForced = false;
+ }
+
+ @Override
+ public boolean isIdle() {
+ return mIdle;
+ }
+
+ @Override
+ public void startTracking(Context context, IdlenessListener listener) {
+ mIdleListener = listener;
+
+ IntentFilter filter = new IntentFilter();
+
+ // State of GarageMode
+ filter.addAction(ACTION_GARAGE_MODE_ON);
+ filter.addAction(ACTION_GARAGE_MODE_OFF);
+
+ // Debugging/instrumentation
+ filter.addAction(ACTION_FORCE_IDLE);
+ filter.addAction(ACTION_UNFORCE_IDLE);
+ filter.addAction(ActivityManagerService.ACTION_TRIGGER_IDLE);
+
+ context.registerReceiver(this, filter);
+ }
+
+ @Override
+ public void dump(PrintWriter pw) {
+ pw.print(" mIdle: "); pw.println(mIdle);
+ pw.print(" mGarageModeOn: "); pw.println(mGarageModeOn);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ logIfDebug("Received action: " + action);
+
+ // Check for forced actions
+ if (action.equals(ACTION_FORCE_IDLE)) {
+ logIfDebug("Forcing idle...");
+ setForceIdleState(true);
+ } else if (action.equals(ACTION_UNFORCE_IDLE)) {
+ logIfDebug("Unforcing idle...");
+ setForceIdleState(false);
+ } else if (action.equals(ACTION_GARAGE_MODE_ON)) {
+ logIfDebug("GarageMode is on...");
+ mGarageModeOn = true;
+ updateIdlenessState();
+ } else if (action.equals(ACTION_GARAGE_MODE_OFF)) {
+ logIfDebug("GarageMode is off...");
+ mGarageModeOn = false;
+ updateIdlenessState();
+ } else if (action.equals(ActivityManagerService.ACTION_TRIGGER_IDLE)) {
+ if (!mGarageModeOn) {
+ logIfDebug("Idle trigger fired...");
+ triggerIdlenessOnce();
+ } else {
+ logIfDebug("TRIGGER_IDLE received but not changing state; idle="
+ + mIdle + " screen=" + mGarageModeOn);
+ }
+ }
+ }
+
+ private void setForceIdleState(boolean forced) {
+ mForced = forced;
+ updateIdlenessState();
+ }
+
+ private void updateIdlenessState() {
+ final boolean newState = (mForced || mGarageModeOn);
+ if (mIdle != newState) {
+ // State of idleness changed. Notifying idleness controller
+ logIfDebug("Device idleness changed. New idle=" + newState);
+ mIdle = newState;
+ mIdleListener.reportNewIdleState(mIdle);
+ } else {
+ // Nothing changed, device idleness is in the same state as new state
+ logIfDebug("Device idleness is the same. Current idle=" + newState);
+ }
+ }
+
+ private void triggerIdlenessOnce() {
+ // This is simply triggering idleness once until some constraint will switch it back off
+ if (mIdle) {
+ // Already in idle state. Nothing to do
+ logIfDebug("Device is already idle");
+ } else {
+ // Going idle once
+ logIfDebug("Device is going idle once");
+ mIdle = true;
+ mIdleListener.reportNewIdleState(mIdle);
+ }
+ }
+
+ private void logIfDebug(String msg) {
+ if (DEBUG) {
+ Slog.v(TAG, msg);
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java b/services/core/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java
new file mode 100644
index 0000000..a85bd40
--- /dev/null
+++ b/services/core/java/com/android/server/job/controllers/idle/DeviceIdlenessTracker.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job.controllers.idle;
+
+import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
+
+import android.app.AlarmManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import android.util.Log;
+import android.util.Slog;
+import com.android.server.am.ActivityManagerService;
+import com.android.server.job.JobSchedulerService;
+
+import java.io.PrintWriter;
+
+public final class DeviceIdlenessTracker extends BroadcastReceiver implements IdlenessTracker {
+ private static final String TAG = "JobScheduler.DeviceIdlenessTracker";
+ private static final boolean DEBUG = JobSchedulerService.DEBUG
+ || Log.isLoggable(TAG, Log.DEBUG);
+
+ private AlarmManager mAlarm;
+
+ // After construction, mutations of idle/screen-on state will only happen
+ // on the main looper thread, either in onReceive() or in an alarm callback.
+ private long mInactivityIdleThreshold;
+ private long mIdleWindowSlop;
+ private boolean mIdle;
+ private boolean mScreenOn;
+ private boolean mDockIdle;
+ private IdlenessListener mIdleListener;
+
+ private AlarmManager.OnAlarmListener mIdleAlarmListener = () -> {
+ handleIdleTrigger();
+ };
+
+ public DeviceIdlenessTracker() {
+ // At boot we presume that the user has just "interacted" with the
+ // device in some meaningful way.
+ mIdle = false;
+ mScreenOn = true;
+ mDockIdle = false;
+ }
+
+ @Override
+ public boolean isIdle() {
+ return mIdle;
+ }
+
+ @Override
+ public void startTracking(Context context, IdlenessListener listener) {
+ mIdleListener = listener;
+ mInactivityIdleThreshold = context.getResources().getInteger(
+ com.android.internal.R.integer.config_jobSchedulerInactivityIdleThreshold);
+ mIdleWindowSlop = context.getResources().getInteger(
+ com.android.internal.R.integer.config_jobSchedulerIdleWindowSlop);
+ mAlarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
+ IntentFilter filter = new IntentFilter();
+
+ // Screen state
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+
+ // Dreaming state
+ filter.addAction(Intent.ACTION_DREAMING_STARTED);
+ filter.addAction(Intent.ACTION_DREAMING_STOPPED);
+
+ // Debugging/instrumentation
+ filter.addAction(ActivityManagerService.ACTION_TRIGGER_IDLE);
+
+ // Wireless charging dock state
+ filter.addAction(Intent.ACTION_DOCK_IDLE);
+ filter.addAction(Intent.ACTION_DOCK_ACTIVE);
+
+ context.registerReceiver(this, filter);
+ }
+
+ @Override
+ public void dump(PrintWriter pw) {
+ pw.print(" mIdle: "); pw.println(mIdle);
+ pw.print(" mScreenOn: "); pw.println(mScreenOn);
+ pw.print(" mDockIdle: "); pw.println(mDockIdle);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (action.equals(Intent.ACTION_SCREEN_ON)
+ || action.equals(Intent.ACTION_DREAMING_STOPPED)
+ || action.equals(Intent.ACTION_DOCK_ACTIVE)) {
+ if (action.equals(Intent.ACTION_DOCK_ACTIVE)) {
+ if (!mScreenOn) {
+ // Ignore this intent during screen off
+ return;
+ } else {
+ mDockIdle = false;
+ }
+ } else {
+ mScreenOn = true;
+ mDockIdle = false;
+ }
+ if (DEBUG) {
+ Slog.v(TAG,"exiting idle : " + action);
+ }
+ //cancel the alarm
+ mAlarm.cancel(mIdleAlarmListener);
+ if (mIdle) {
+ // possible transition to not-idle
+ mIdle = false;
+ mIdleListener.reportNewIdleState(mIdle);
+ }
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)
+ || action.equals(Intent.ACTION_DREAMING_STARTED)
+ || action.equals(Intent.ACTION_DOCK_IDLE)) {
+ // when the screen goes off or dreaming starts or wireless charging dock in idle,
+ // we schedule the alarm that will tell us when we have decided the device is
+ // truly idle.
+ if (action.equals(Intent.ACTION_DOCK_IDLE)) {
+ if (!mScreenOn) {
+ // Ignore this intent during screen off
+ return;
+ } else {
+ mDockIdle = true;
+ }
+ } else {
+ mScreenOn = false;
+ mDockIdle = false;
+ }
+ final long nowElapsed = sElapsedRealtimeClock.millis();
+ final long when = nowElapsed + mInactivityIdleThreshold;
+ if (DEBUG) {
+ Slog.v(TAG, "Scheduling idle : " + action + " now:" + nowElapsed + " when="
+ + when);
+ }
+ mAlarm.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+ when, mIdleWindowSlop, "JS idleness", mIdleAlarmListener, null);
+ } else if (action.equals(ActivityManagerService.ACTION_TRIGGER_IDLE)) {
+ handleIdleTrigger();
+ }
+ }
+
+ private void handleIdleTrigger() {
+ // idle time starts now. Do not set mIdle if screen is on.
+ if (!mIdle && (!mScreenOn || mDockIdle)) {
+ if (DEBUG) {
+ Slog.v(TAG, "Idle trigger fired @ " + sElapsedRealtimeClock.millis());
+ }
+ mIdle = true;
+ mIdleListener.reportNewIdleState(mIdle);
+ } else {
+ if (DEBUG) {
+ Slog.v(TAG, "TRIGGER_IDLE received but not changing state; idle="
+ + mIdle + " screen=" + mScreenOn);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/job/controllers/idle/IdlenessListener.java b/services/core/java/com/android/server/job/controllers/idle/IdlenessListener.java
new file mode 100644
index 0000000..7ffd7cd
--- /dev/null
+++ b/services/core/java/com/android/server/job/controllers/idle/IdlenessListener.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job.controllers.idle;
+
+/**
+ * Interface through which an IdlenessTracker informs the job scheduler of
+ * changes in the device's inactivity state.
+ */
+public interface IdlenessListener {
+ /**
+ * Tell the job scheduler that the device's idle state has changed.
+ *
+ * @param deviceIsIdle {@code true} to indicate that the device is now considered
+ * to be idle; {@code false} to indicate that the device is now being interacted with,
+ * so jobs with idle constraints should not be run.
+ */
+ void reportNewIdleState(boolean deviceIsIdle);
+}
diff --git a/services/core/java/com/android/server/job/controllers/idle/IdlenessTracker.java b/services/core/java/com/android/server/job/controllers/idle/IdlenessTracker.java
new file mode 100644
index 0000000..09f01c2
--- /dev/null
+++ b/services/core/java/com/android/server/job/controllers/idle/IdlenessTracker.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.job.controllers.idle;
+
+import android.content.Context;
+
+import java.io.PrintWriter;
+
+public interface IdlenessTracker {
+ /**
+ * One-time initialization: this method is called once, after construction of
+ * the IdlenessTracker instance. This is when the tracker should actually begin
+ * monitoring whatever signals it consumes in deciding when the device is in a
+ * non-interacting state. When the idle state changes thereafter, the given
+ * listener must be called to report the new state.
+ */
+ void startTracking(Context context, IdlenessListener listener);
+
+ /**
+ * Report whether the device is currently considered "idle" for purposes of
+ * running scheduled jobs with idleness constraints.
+ *
+ * @return {@code true} if the job scheduler should consider idleness
+ * constraints to be currently satisfied; {@code false} otherwise.
+ */
+ boolean isIdle();
+
+ /**
+ * Dump useful information about tracked idleness-related state in plaintext.
+ */
+ void dump(PrintWriter pw);
+}
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index 74930c8..4243f02 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -45,7 +45,7 @@
/*
* Local flag to enable debug logging.
*/
- private static final boolean DEBUG_LOG_ENABLED = true;
+ private static final boolean DEBUG_LOG_ENABLED = false;
/*
* The context of the service.
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index dc95d41..27509de 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -77,6 +77,11 @@
private static final int OS_APP_INSTANCE = -1;
+ /*
+ * Local flag to enable debug logging.
+ */
+ private static final boolean DEBUG_LOG_ENABLED = false;
+
private final Context mContext;
private final Map<Integer, ContextHubInfo> mContextHubIdToInfoMap;
@@ -779,12 +784,16 @@
int msgVersion = 0;
int callbacksCount = mCallbacksList.beginBroadcast();
- Log.d(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle " +
- contextHubHandle + ", appInstance " + appInstance + ", callBackCount "
- + callbacksCount);
+ if (DEBUG_LOG_ENABLED) {
+ Log.v(TAG, "Sending message " + msgType + " version " + msgVersion + " from hubHandle "
+ + contextHubHandle + ", appInstance " + appInstance + ", callBackCount "
+ + callbacksCount);
+ }
if (callbacksCount < 1) {
- Log.v(TAG, "No message callbacks registered.");
+ if (DEBUG_LOG_ENABLED) {
+ Log.v(TAG, "No message callbacks registered.");
+ }
return 0;
}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index af4f426..efc18ad 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -517,6 +517,30 @@
return false;
}
+ protected boolean isPackageAllowed(String pkg, int userId) {
+ if (pkg == null) {
+ return false;
+ }
+ ArrayMap<Boolean, ArraySet<String>> allowedByType =
+ mApproved.getOrDefault(userId, new ArrayMap<>());
+ for (int i = 0; i < allowedByType.size(); i++) {
+ ArraySet<String> allowed = allowedByType.valueAt(i);
+ for (String allowedEntry : allowed) {
+ ComponentName component = ComponentName.unflattenFromString(allowedEntry);
+ if (component != null) {
+ if (pkg.equals(component.getPackageName())) {
+ return true;
+ }
+ } else {
+ if (pkg.equals(allowedEntry)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
public void onPackagesChanged(boolean removingPackage, String[] pkgList, int[] uidList) {
if (DEBUG) Slog.d(TAG, "onPackagesChanged removingPackage=" + removingPackage
+ " pkgList=" + (pkgList == null ? null : Arrays.asList(pkgList))
@@ -537,6 +561,11 @@
if (mEnabledServicesPackageNames.contains(pkgName)) {
anyServicesInvolved = true;
}
+ for (int uid : uidList) {
+ if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) {
+ anyServicesInvolved = true;
+ }
+ }
}
if (anyServicesInvolved) {
@@ -600,6 +629,15 @@
+ service + " " + service.getClass());
}
+ public boolean isSameUser(IInterface service, int userId) {
+ checkNotNull(service);
+ ManagedServiceInfo info = getServiceFromTokenLocked(service);
+ if (info != null) {
+ return info.isSameUser(userId);
+ }
+ return false;
+ }
+
public void unregisterService(IInterface service, int userid) {
checkNotNull(service);
// no need to check permissions; if your service binder is in the list,
@@ -650,7 +688,11 @@
for (int userId : userIds) {
if (enabled) {
- registerServiceLocked(component, userId);
+ if (isPackageOrComponentAllowed(component.toString(), userId)) {
+ registerServiceLocked(component, userId);
+ } else {
+ Slog.d(TAG, component + " no longer has permission to be bound");
+ }
} else {
unregisterServiceLocked(component, userId);
}
@@ -1172,6 +1214,13 @@
proto.end(token);
}
+ public boolean isSameUser(int userId) {
+ if (!isEnabledForCurrentProfiles()) {
+ return false;
+ }
+ return this.userid == userId;
+ }
+
public boolean enabledAndUserMatches(int nid) {
if (!isEnabledForCurrentProfiles()) {
return false;
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5a0578f..de53427 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -3450,7 +3450,8 @@
for (int i = 0; i < N; i++) {
final NotificationRecord r = mEnqueuedNotifications.get(i);
if (Objects.equals(adjustment.getKey(), r.getKey())
- && Objects.equals(adjustment.getUser(), r.getUserId())) {
+ && Objects.equals(adjustment.getUser(), r.getUserId())
+ && mAssistants.isSameUser(token, r.getUserId())) {
applyAdjustment(r, adjustment);
r.applyAdjustments();
foundEnqueued = true;
@@ -3470,17 +3471,9 @@
@Override
public void applyAdjustmentFromAssistant(INotificationListener token,
Adjustment adjustment) {
- final long identity = Binder.clearCallingIdentity();
- try {
- synchronized (mNotificationLock) {
- mAssistants.checkServiceTokenLocked(token);
- NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
- applyAdjustment(n, adjustment);
- }
- mRankingHandler.requestSort();
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
+ List<Adjustment> adjustments = new ArrayList<>();
+ adjustments.add(adjustment);
+ applyAdjustmentsFromAssistant(token, adjustments);
}
@Override
@@ -3489,14 +3482,20 @@
final long identity = Binder.clearCallingIdentity();
try {
+ boolean appliedAdjustment = false;
synchronized (mNotificationLock) {
mAssistants.checkServiceTokenLocked(token);
for (Adjustment adjustment : adjustments) {
- NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
- applyAdjustment(n, adjustment);
+ NotificationRecord r = mNotificationsByKey.get(adjustment.getKey());
+ if (r != null && mAssistants.isSameUser(token, r.getUserId())) {
+ applyAdjustment(r, adjustment);
+ appliedAdjustment = true;
+ }
}
}
- mRankingHandler.requestSort();
+ if (appliedAdjustment) {
+ mRankingHandler.requestSort();
+ }
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4032,6 +4031,7 @@
+ " notification=" + notification);
}
checkCallerIsSystemOrSameApp(pkg);
+ checkRestrictedCategories(notification);
final int userId = ActivityManager.handleIncomingUser(callingPid,
callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
@@ -5273,6 +5273,7 @@
ArrayList<Integer> userSentimentBefore = new ArrayList<>(N);
ArrayList<Integer> suppressVisuallyBefore = new ArrayList<>(N);
ArrayList<ArrayList<Notification.Action>> smartActionsBefore = new ArrayList<>(N);
+ ArrayList<ArrayList<CharSequence>> smartRepliesBefore = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
final NotificationRecord r = mNotificationList.get(i);
orderBefore.add(r.getKey());
@@ -5285,6 +5286,7 @@
userSentimentBefore.add(r.getUserSentiment());
suppressVisuallyBefore.add(r.getSuppressedVisualEffects());
smartActionsBefore.add(r.getSmartActions());
+ smartRepliesBefore.add(r.getSmartReplies());
mRankingHelper.extractSignals(r);
}
mRankingHelper.sort(mNotificationList);
@@ -5300,7 +5302,8 @@
|| !Objects.equals(userSentimentBefore.get(i), r.getUserSentiment())
|| !Objects.equals(suppressVisuallyBefore.get(i),
r.getSuppressedVisualEffects())
- || !Objects.equals(smartActionsBefore.get(i), r.getSmartActions())) {
+ || !Objects.equals(smartActionsBefore.get(i), r.getSmartActions())
+ || !Objects.equals(smartRepliesBefore.get(i), r.getSmartReplies())) {
mHandler.scheduleSendRankingUpdate();
return;
}
@@ -6198,6 +6201,26 @@
checkCallerIsSameApp(pkg);
}
+ /**
+ * Check if the notification is of a category type that is restricted to system use only,
+ * if so throw SecurityException
+ */
+ private void checkRestrictedCategories(final Notification notification) {
+ try {
+ if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0)) {
+ return;
+ }
+ } catch (RemoteException re) {
+ if (DBG) Log.e(TAG, "Unable to confirm if it's safe to skip category "
+ + "restrictions check thus the check will be done anyway");
+ }
+ if (Notification.CATEGORY_CAR_EMERGENCY.equals(notification.category)
+ || Notification.CATEGORY_CAR_WARNING.equals(notification.category)
+ || Notification.CATEGORY_CAR_INFORMATION.equals(notification.category)) {
+ checkCallerIsSystem();
+ }
+ }
+
private boolean isCallerInstantApp(String pkg) {
// System is always allowed to act for ephemeral apps.
if (isCallerSystemOrPhone()) {
@@ -6277,6 +6300,7 @@
Bundle userSentiment = new Bundle();
Bundle hidden = new Bundle();
Bundle smartActions = new Bundle();
+ Bundle smartReplies = new Bundle();
for (int i = 0; i < N; i++) {
NotificationRecord record = mNotificationList.get(i);
if (!isVisibleToListener(record.sbn, info)) {
@@ -6305,6 +6329,7 @@
userSentiment.putInt(key, record.getUserSentiment());
hidden.putBoolean(key, record.isHidden());
smartActions.putParcelableArrayList(key, record.getSmartActions());
+ smartReplies.putCharSequenceArrayList(key, record.getSmartReplies());
}
final int M = keys.size();
String[] keysAr = keys.toArray(new String[M]);
@@ -6316,7 +6341,7 @@
return new NotificationRankingUpdate(keysAr, interceptedKeysAr, visibilityOverrides,
suppressedVisualEffects, importanceAr, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, hidden,
- smartActions);
+ smartActions, smartReplies);
}
boolean hasCompanionDevice(ManagedServiceInfo info) {
@@ -6468,7 +6493,8 @@
// There should be only one, but it's a list, so while we enforce
// singularity elsewhere, we keep it general here, to avoid surprises.
for (final ManagedServiceInfo info : NotificationAssistants.this.getServices()) {
- boolean sbnVisible = isVisibleToListener(sbn, info);
+ boolean sbnVisible = isVisibleToListener(sbn, info)
+ && info.isSameUser(r.getUserId());
if (!sbnVisible) {
continue;
}
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index f32b338..469828b 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -162,6 +162,7 @@
private String mGroupLogTag;
private String mChannelIdLogTag;
private ArrayList<Notification.Action> mSmartActions;
+ private ArrayList<CharSequence> mSmartReplies;
private final List<Adjustment> mAdjustments;
private final NotificationStats mStats;
@@ -637,6 +638,9 @@
if (signals.containsKey(Adjustment.KEY_SMART_ACTIONS)) {
setSmartActions(signals.getParcelableArrayList(Adjustment.KEY_SMART_ACTIONS));
}
+ if (signals.containsKey(Adjustment.KEY_SMART_REPLIES)) {
+ setSmartReplies(signals.getCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES));
+ }
}
}
}
@@ -1064,6 +1068,14 @@
return mSmartActions;
}
+ public void setSmartReplies(ArrayList<CharSequence> smartReplies) {
+ mSmartReplies = smartReplies;
+ }
+
+ public ArrayList<CharSequence> getSmartReplies() {
+ return mSmartReplies;
+ }
+
/**
* @return all {@link Uri} that should have permission granted to whoever
* will be rendering it. This list has already been vetted to only
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 9c5e064..7149720 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -508,8 +508,8 @@
public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) {
setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/);
- Settings.Global.putInt(mContext.getContentResolver(), Global.SHOW_ZEN_SETTINGS_SUGGESTION,
- 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 0);
}
private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller,
@@ -612,7 +612,11 @@
config.manualRule = null; // don't restore the manual rule
}
- boolean resetToDefaultRules = true;
+ // booleans to determine whether to reset the rules to the default rules
+ boolean allRulesDisabled = true;
+ boolean hasDefaultRules = config.automaticRules.containsAll(
+ ZenModeConfig.DEFAULT_RULE_IDS);
+
long time = System.currentTimeMillis();
if (config.automaticRules != null && config.automaticRules.size() > 0) {
for (ZenRule automaticRule : config.automaticRules.values()) {
@@ -622,25 +626,28 @@
automaticRule.condition = null;
automaticRule.creationTime = time;
}
- resetToDefaultRules &= !automaticRule.enabled;
+
+ allRulesDisabled &= !automaticRule.enabled;
}
}
- if (config.version < ZenModeConfig.XML_VERSION || forRestore) {
- Settings.Global.putInt(mContext.getContentResolver(),
- Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
+ if (!hasDefaultRules && allRulesDisabled
+ && (forRestore || config.version < ZenModeConfig.XML_VERSION)) {
+ // reset zen automatic rules to default on restore or upgrade if:
+ // - doesn't already have default rules and
+ // - all previous automatic rules were disabled
+ config.automaticRules = new ArrayMap<>();
+ appendDefaultRules(config);
+ reason += ", reset to default rules";
+ }
- // resets zen automatic rules to default
- // if all prev auto rules were disabled on update
- if (resetToDefaultRules) {
- config.automaticRules = new ArrayMap<>();
- appendDefaultRules(config);
- reason += ", reset to default rules";
- }
+ if (config.version < ZenModeConfig.XML_VERSION) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 1);
} else {
// devices not restoring/upgrading already have updated zen settings
- Settings.Global.putInt(mContext.getContentResolver(),
- Global.ZEN_SETTINGS_UPDATED, 1);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_UPDATED, 1);
}
if (DEBUG) Log.d(TAG, reason);
synchronized (mConfig) {
@@ -824,10 +831,10 @@
if (automaticRule.isAutomaticActive()) {
if (zenSeverity(automaticRule.zenMode) > zenSeverity(zen)) {
// automatic rule triggered dnd and user hasn't seen update dnd dialog
- if (Settings.Global.getInt(mContext.getContentResolver(),
- Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1) == 0) {
- Settings.Global.putInt(mContext.getContentResolver(),
- Global.SHOW_ZEN_SETTINGS_SUGGESTION, 1);
+ if (Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ZEN_SETTINGS_SUGGESTION_VIEWED, 1) == 0) {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 1);
}
zen = automaticRule.zenMode;
}
@@ -1192,18 +1199,18 @@
&& zen != Global.ZEN_MODE_OFF
&& !isWatch
&& Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 0) != 0;
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0) != 0;
if (isWatch) {
Settings.Global.putInt(mContext.getContentResolver(),
- Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
}
if (showNotification) {
mNotificationManager.notify(TAG, SystemMessage.NOTE_ZEN_UPGRADE,
createZenUpgradeNotification());
- Settings.Global.putInt(mContext.getContentResolver(),
- Global.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ Settings.Secure.SHOW_ZEN_UPGRADE_NOTIFICATION, 0);
}
}
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index 38b9024..06f67cd 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -1176,15 +1176,13 @@
private final class CookiePersistence extends Handler {
private static final long PERSIST_COOKIE_DELAY_MILLIS = 1000L; /* one second */
- // In case you wonder why we stash the cookies aside, we use
- // the user id for the message id and the package for the payload.
- // Handler allows removing messages by id and tag where the
- // tag is compared using ==. So to allow cancelling the
- // pending persistence for an app under a given user we use
- // the fact that package are cached by the system so the ==
- // comparison would match and we end up with a way to cancel
- // persisting the cookie for a user and package.
- private final SparseArray<ArrayMap<PackageParser.Package, SomeArgs>> mPendingPersistCookies
+ // The cookies are cached per package name per user-id in this sparse
+ // array. The caching is so that pending persistence can be canceled within
+ // a short interval. To ensure we still return pending persist cookies
+ // for a package that uninstalled and reinstalled while the persistence
+ // was still pending, we use the package name as a key for
+ // mPendingPersistCookies, since that stays stable across reinstalls.
+ private final SparseArray<ArrayMap<String, SomeArgs>> mPendingPersistCookies
= new SparseArray<>();
public CookiePersistence(Looper looper) {
@@ -1214,10 +1212,10 @@
public @Nullable byte[] getPendingPersistCookieLPr(@NonNull PackageParser.Package pkg,
@UserIdInt int userId) {
- ArrayMap<PackageParser.Package, SomeArgs> pendingWorkForUser =
+ ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
if (pendingWorkForUser != null) {
- SomeArgs state = pendingWorkForUser.get(pkg);
+ SomeArgs state = pendingWorkForUser.get(pkg.packageName);
if (state != null) {
return (byte[]) state.arg1;
}
@@ -1237,7 +1235,7 @@
private void addPendingPersistCookieLPw(@UserIdInt int userId,
@NonNull PackageParser.Package pkg, @NonNull byte[] cookie,
@NonNull File cookieFile) {
- ArrayMap<PackageParser.Package, SomeArgs> pendingWorkForUser =
+ ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
if (pendingWorkForUser == null) {
pendingWorkForUser = new ArrayMap<>();
@@ -1246,16 +1244,16 @@
SomeArgs args = SomeArgs.obtain();
args.arg1 = cookie;
args.arg2 = cookieFile;
- pendingWorkForUser.put(pkg, args);
+ pendingWorkForUser.put(pkg.packageName, args);
}
private SomeArgs removePendingPersistCookieLPr(@NonNull PackageParser.Package pkg,
@UserIdInt int userId) {
- ArrayMap<PackageParser.Package, SomeArgs> pendingWorkForUser =
+ ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
SomeArgs state = null;
if (pendingWorkForUser != null) {
- state = pendingWorkForUser.remove(pkg);
+ state = pendingWorkForUser.remove(pkg.packageName);
if (pendingWorkForUser.isEmpty()) {
mPendingPersistCookies.remove(userId);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ac33454..3d6b3fb 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3241,7 +3241,7 @@
mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
SharedLibraryInfo.VERSION_UNDEFINED);
- mRequiredPermissionControllerPackage = getRequiredPermissionsControllerLPr();
+ mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();
} else {
mRequiredVerifierPackage = null;
mRequiredInstallerPackage = null;
@@ -3598,7 +3598,7 @@
return resolveInfo.getComponentInfo().packageName;
}
- private @NonNull String getRequiredPermissionsControllerLPr() {
+ private @NonNull String getRequiredPermissionControllerLPr() {
final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
intent.addCategory(Intent.CATEGORY_DEFAULT);
@@ -19565,7 +19565,7 @@
// If permission review is enabled and this is a legacy app, mark the
// permission as requiring a review as this is the initial state.
int flags = 0;
- if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
+ if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) {
flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
}
if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
@@ -23972,6 +23972,8 @@
return mRequiredVerifierPackage;
case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
return mSystemTextClassifierPackage;
+ case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
+ return mRequiredPermissionControllerPackage;
}
return null;
}
@@ -24447,6 +24449,23 @@
PackageManagerService.this.setCheckPermissionDelegateLocked(delegate);
}
}
+
+ @Override
+ public SparseArray<String> getAppsWithSharedUserIds() {
+ synchronized (mPackages) {
+ return getAppsWithSharedUserIdsLocked();
+ }
+ }
+ }
+
+ private SparseArray<String> getAppsWithSharedUserIdsLocked() {
+ final SparseArray<String> sharedUserIds = new SparseArray<>();
+ synchronized (mPackages) {
+ for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
+ sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
+ }
+ }
+ return sharedUserIds;
}
@Override
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 76832ed..9dc0b29 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1267,9 +1267,15 @@
// we still want to blindly grant it to old apps.
allowed = true;
}
+ // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
+ // need a separate flag anymore. Hence we need to check which
+ // permissions are needed by the permission controller
if (!allowed && bp.isInstaller()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
- PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))) {
+ && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
+ || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
+ UserHandle.USER_SYSTEM)))) {
// If this permission is to be granted to the system installer and
// this app is an installer, then it gets the permission.
allowed = true;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 8ef1196..a8b92a6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -288,6 +288,8 @@
import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
import com.android.server.wm.AppTransition;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.DisplayPolicy;
+import com.android.server.wm.DisplayRotation;
import com.android.server.wm.WindowFrames;
import com.android.server.wm.WindowManagerInternal;
import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
@@ -500,8 +502,6 @@
WindowState mStatusBar = null;
private final int[] mStatusBarHeightForRotation = new int[4];
WindowState mNavigationBar = null;
- boolean mHasNavigationBar = false;
- boolean mNavigationBarCanMove = false; // can the navigation bar ever move to the side?
@NavigationBarPosition
int mNavigationBarPosition = NAV_BAR_BOTTOM;
int[] mNavigationBarHeightForRotationDefault = new int[4];
@@ -556,8 +556,6 @@
volatile boolean mRecentsVisible;
volatile boolean mNavBarVirtualKeyHapticFeedbackEnabled = true;
volatile boolean mPictureInPictureVisible;
- // Written by vr manager thread, only read in this class.
- volatile private boolean mPersistentVrModeEnabled;
volatile private boolean mDismissImeOnBackKeyPressed;
// Used to hold the last user key used to wake the device. This helps us prevent up events
@@ -567,40 +565,18 @@
int mRecentAppsHeldModifiers;
boolean mLanguageSwitchKeyPressed;
- int mLidState = LID_ABSENT;
int mCameraLensCoverState = CAMERA_LENS_COVER_ABSENT;
boolean mHaveBuiltInKeyboard;
boolean mSystemReady;
boolean mSystemBooted;
- boolean mHdmiPlugged;
HdmiControl mHdmiControl;
IUiModeManager mUiModeManager;
int mUiMode;
- int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
- int mLidOpenRotation;
- int mCarDockRotation;
- int mDeskDockRotation;
- int mUndockedHdmiRotation;
- int mDemoHdmiRotation;
- boolean mDemoHdmiRotationLock;
- int mDemoRotation;
- boolean mDemoRotationLock;
boolean mWakeGestureEnabledSetting;
MyWakeGestureListener mWakeGestureListener;
- // Default display does not rotate, apps that require non-default orientation will have to
- // have the orientation emulated.
- private boolean mForceDefaultOrientation = false;
-
- int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
- int mUserRotation = Surface.ROTATION_0;
-
- boolean mSupportAutoRotation;
- int mAllowAllRotations = -1;
- boolean mCarDockEnablesAccelerometer;
- boolean mDeskDockEnablesAccelerometer;
int mLidKeyboardAccessibility;
int mLidNavigationAccessibility;
boolean mLidControlsScreenLock;
@@ -613,14 +589,6 @@
int mLongPressOnBackBehavior;
int mShortPressOnSleepBehavior;
int mShortPressOnWindowBehavior;
- volatile boolean mAwake;
- boolean mScreenOnEarly;
- boolean mScreenOnFully;
- ScreenOnListener mScreenOnListener;
- boolean mKeyguardDrawComplete;
- boolean mWindowManagerDrawComplete;
- boolean mOrientationSensorEnabled = false;
- int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
boolean mHasSoftInput = false;
boolean mTranslucentDecorEnabled = true;
boolean mUseTvRouting;
@@ -729,18 +697,14 @@
// Behavior of Back button while in-call and screen on
int mIncallBackBehavior;
- // Behavior of rotation suggestions. (See Settings.Secure.SHOW_ROTATION_SUGGESTION)
- int mShowRotationSuggestions;
-
// Whether system navigation keys are enabled
boolean mSystemNavigationKeysEnabled;
- Display mDisplay;
-
- int mLandscapeRotation = 0; // default landscape rotation
- int mSeascapeRotation = 0; // "other" landscape rotation, 180 degrees from mLandscapeRotation
- int mPortraitRotation = 0; // default portrait rotation
- int mUpsideDownRotation = 0; // "other" portrait rotation
+ // TODO(b/111361251): Remove default when the dependencies are multi-display ready.
+ Display mDefaultDisplay;
+ DisplayRotation mDefaultDisplayRotation;
+ DisplayPolicy mDefaultDisplayPolicy;
+ WindowOrientationListener mDefaultOrientationListener;
// What we do when the user long presses on home
private int mLongPressOnHomeBehavior;
@@ -963,7 +927,7 @@
private UEventObserver mHDMIObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
- setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
+ mDefaultDisplayPolicy.setHdmiPlugged("1".equals(event.get("SWITCH_STATE")));
}
};
@@ -988,12 +952,6 @@
Settings.Secure.WAKE_GESTURE_ENABLED), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.ACCELEROMETER_ROTATION), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.USER_ROTATION), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
@@ -1006,9 +964,6 @@
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.SHOW_ROTATION_SUGGESTIONS), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.VOLUME_HUSH_GESTURE), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
@@ -1043,53 +998,11 @@
}
}
- class MyOrientationListener extends WindowOrientationListener {
-
- private SparseArray<Runnable> mRunnableCache;
-
- MyOrientationListener(Context context, Handler handler) {
- super(context, handler);
- mRunnableCache = new SparseArray<>(5);
- }
-
- private class UpdateRunnable implements Runnable {
- private final int mRotation;
- UpdateRunnable(int rotation) {
- mRotation = rotation;
- }
-
- @Override
- public void run() {
- // send interaction hint to improve redraw performance
- mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
- if (isRotationChoicePossible(mCurrentAppOrientation)) {
- final boolean isValid = isValidRotationChoice(mCurrentAppOrientation,
- mRotation);
- sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
- } else {
- updateRotation(false);
- }
- }
- }
-
- @Override
- public void onProposedRotationChanged(int rotation) {
- if (localLOGV) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
- Runnable r = mRunnableCache.get(rotation, null);
- if (r == null){
- r = new UpdateRunnable(rotation);
- mRunnableCache.put(rotation, r);
- }
- mHandler.post(r);
- }
- }
- MyOrientationListener mOrientationListener;
-
final IPersistentVrStateCallbacks mPersistentVrModeListener =
new IPersistentVrStateCallbacks.Stub() {
@Override
public void onPersistentVrStateChanged(boolean enabled) {
- mPersistentVrModeEnabled = enabled;
+ mDefaultDisplayPolicy.setPersistentVrModeEnabled(enabled);
}
};
@@ -1171,100 +1084,6 @@
}
}
- /*
- * We always let the sensor be switched on by default except when
- * the user has explicitly disabled sensor based rotation or when the
- * screen is switched off.
- */
- boolean needSensorRunningLp() {
- if (mSupportAutoRotation) {
- if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
- || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
- // If the application has explicitly requested to follow the
- // orientation, then we need to turn the sensor on.
- return true;
- }
- }
- if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR) ||
- (mDeskDockEnablesAccelerometer && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) {
- // enable accelerometer if we are docked in a dock that enables accelerometer
- // orientation management,
- return true;
- }
- if (mUserRotationMode == USER_ROTATION_LOCKED) {
- // If the setting for using the sensor by default is enabled, then
- // we will always leave it on. Note that the user could go to
- // a window that forces an orientation that does not use the
- // sensor and in theory we could turn it off... however, when next
- // turning it on we won't have a good value for the current
- // orientation for a little bit, which can cause orientation
- // changes to lag, so we'd like to keep it always on. (It will
- // still be turned off when the screen is off.)
-
- // When locked we can provide rotation suggestions users can approve to change the
- // current screen rotation. To do this the sensor needs to be running.
- return mSupportAutoRotation &&
- mShowRotationSuggestions == Settings.Secure.SHOW_ROTATION_SUGGESTIONS_ENABLED;
- }
- return mSupportAutoRotation;
- }
-
- /*
- * Various use cases for invoking this function
- * screen turning off, should always disable listeners if already enabled
- * screen turned on and current app has sensor based orientation, enable listeners
- * if not already enabled
- * screen turned on and current app does not have sensor orientation, disable listeners if
- * already enabled
- * screen turning on and current app has sensor based orientation, enable listeners if needed
- * screen turning on and current app has nosensor based orientation, do nothing
- */
- void updateOrientationListenerLp() {
- if (!mOrientationListener.canDetectOrientation()) {
- // If sensor is turned off or nonexistent for some reason
- return;
- }
- // Could have been invoked due to screen turning on or off or
- // change of the currently visible window's orientation.
- if (localLOGV) Slog.v(TAG, "mScreenOnEarly=" + mScreenOnEarly
- + ", mAwake=" + mAwake + ", mCurrentAppOrientation=" + mCurrentAppOrientation
- + ", mOrientationSensorEnabled=" + mOrientationSensorEnabled
- + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
- + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
-
- boolean disable = true;
- // Note: We postpone the rotating of the screen until the keyguard as well as the
- // window manager have reported a draw complete or the keyguard is going away in dismiss
- // mode.
- if (mScreenOnEarly && mAwake && ((mKeyguardDrawComplete && mWindowManagerDrawComplete))) {
- if (needSensorRunningLp()) {
- disable = false;
- //enable listener if not already enabled
- if (!mOrientationSensorEnabled) {
- // Don't clear the current sensor orientation if the keyguard is going away in
- // dismiss mode. This allows window manager to use the last sensor reading to
- // determine the orientation vs. falling back to the last known orientation if
- // the sensor reading was cleared which can cause it to relaunch the app that
- // will show in the wrong orientation first before correcting leading to app
- // launch delays.
- mOrientationListener.enable(true /* clearCurrentRotation */);
- if(localLOGV) Slog.v(TAG, "Enabling listeners");
- mOrientationSensorEnabled = true;
- }
- }
- }
- //check if sensors need to be disabled
- if (disable && mOrientationSensorEnabled) {
- mOrientationListener.disable();
- if(localLOGV) Slog.v(TAG, "Disabling listeners");
- mOrientationSensorEnabled = false;
- }
- }
-
private void interceptBackKeyDown() {
MetricsLogger.count(mContext, "key_back_down", 1);
// Reset back key state for long press
@@ -1490,7 +1309,7 @@
}
private void powerPress(long eventTime, boolean interactive, int count) {
- if (mScreenOnEarly && !mScreenOnFully) {
+ if (mDefaultDisplayPolicy.isScreenOnEarly() && !mDefaultDisplayPolicy.isScreenOnFully()) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
return;
@@ -1990,6 +1809,14 @@
return mContext.getResources().getConfiguration().isScreenRound();
}
+ @Override
+ public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
+ mDefaultDisplay = displayContentInfo.getDisplay();
+ mDefaultDisplayRotation = displayContentInfo.getDisplayRotation();
+ mDefaultDisplayPolicy = mDefaultDisplayRotation.getDisplayPolicy();
+ mDefaultOrientationListener = mDefaultDisplayRotation.getOrientationListener();
+ }
+
/** {@inheritDoc} */
@Override
public void init(Context context, IWindowManager windowManager,
@@ -2046,10 +1873,6 @@
mHandler = new PolicyHandler();
mWakeGestureListener = new MyWakeGestureListener(mContext, mHandler);
- mOrientationListener = new MyOrientationListener(mContext, mHandler);
- try {
- mOrientationListener.setCurrentRotation(windowManager.getDefaultDisplayRotation());
- } catch (RemoteException ex) { }
mSettingsObserver = new SettingsObserver(mHandler);
mSettingsObserver.observe();
mShortcutManager = new ShortcutManager(context);
@@ -2080,20 +1903,6 @@
mPowerKeyWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"PhoneWindowManager.mPowerKeyWakeLock");
mEnableShiftMenuBugReports = "1".equals(SystemProperties.get("ro.debuggable"));
- mSupportAutoRotation = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_supportAutoRotation);
- mLidOpenRotation = readRotation(
- com.android.internal.R.integer.config_lidOpenRotation);
- mCarDockRotation = readRotation(
- com.android.internal.R.integer.config_carDockRotation);
- mDeskDockRotation = readRotation(
- com.android.internal.R.integer.config_deskDockRotation);
- mUndockedHdmiRotation = readRotation(
- com.android.internal.R.integer.config_undockedHdmiRotation);
- mCarDockEnablesAccelerometer = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_carDockEnablesAccelerometer);
- mDeskDockEnablesAccelerometer = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
mLidKeyboardAccessibility = mContext.getResources().getInteger(
com.android.internal.R.integer.config_lidKeyboardAccessibility);
mLidNavigationAccessibility = mContext.getResources().getInteger(
@@ -2167,8 +1976,8 @@
Intent intent = context.registerReceiver(mDockReceiver, filter);
if (intent != null) {
// Retrieve current sticky dock event broadcast.
- mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
- Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ mDefaultDisplayPolicy.setDockMode(intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+ Intent.EXTRA_DOCK_STATE_UNDOCKED));
}
// register for dream-related broadcasts
@@ -2222,11 +2031,11 @@
}
@Override
public void onDown() {
- mOrientationListener.onTouchStart();
+ mDefaultOrientationListener.onTouchStart();
}
@Override
public void onUpOrCancel() {
- mOrientationListener.onTouchEnd();
+ mDefaultOrientationListener.onTouchEnd();
}
@Override
public void onMouseHoverAtTop() {
@@ -2333,110 +2142,12 @@
com.android.internal.R.integer.config_navBarOpacityMode);
}
- @Override
- public void setInitialDisplaySize(Display display, int width, int height, int density) {
- // This method might be called before the policy has been fully initialized
- // or for other displays we don't care about.
- // TODO(multi-display): Define policy for secondary displays.
- if (mContext == null || display.getDisplayId() != DEFAULT_DISPLAY) {
- return;
- }
- mDisplay = display;
-
- final Resources res = mContext.getResources();
- int shortSize, longSize;
- if (width > height) {
- shortSize = height;
- longSize = width;
- mLandscapeRotation = Surface.ROTATION_0;
- mSeascapeRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
- mPortraitRotation = Surface.ROTATION_90;
- mUpsideDownRotation = Surface.ROTATION_270;
- } else {
- mPortraitRotation = Surface.ROTATION_270;
- mUpsideDownRotation = Surface.ROTATION_90;
- }
- } else {
- shortSize = width;
- longSize = height;
- mPortraitRotation = Surface.ROTATION_0;
- mUpsideDownRotation = Surface.ROTATION_180;
- if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
- mLandscapeRotation = Surface.ROTATION_270;
- mSeascapeRotation = Surface.ROTATION_90;
- } else {
- mLandscapeRotation = Surface.ROTATION_90;
- mSeascapeRotation = Surface.ROTATION_270;
- }
- }
-
- // SystemUI (status bar) layout policy
- int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density;
- int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density;
-
- // Allow the navigation bar to move on non-square small devices (phones).
- mNavigationBarCanMove = width != height && shortSizeDp < 600;
-
- mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
-
- // Allow a system property to override this. Used by the emulator.
- // See also hasNavigationBar().
- String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
- if ("1".equals(navBarOverride)) {
- mHasNavigationBar = false;
- } else if ("0".equals(navBarOverride)) {
- mHasNavigationBar = true;
- }
-
- // For demo purposes, allow the rotation of the HDMI display to be controlled.
- // By default, HDMI locks rotation to landscape.
- if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
- mDemoHdmiRotation = mPortraitRotation;
- } else {
- mDemoHdmiRotation = mLandscapeRotation;
- }
- mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
-
- // For demo purposes, allow the rotation of the remote display to be controlled.
- // By default, remote display locks rotation to landscape.
- if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) {
- mDemoRotation = mPortraitRotation;
- } else {
- mDemoRotation = mLandscapeRotation;
- }
- mDemoRotationLock = SystemProperties.getBoolean(
- "persist.demo.rotationlock", false);
-
- // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
- // http://developer.android.com/guide/practices/screens_support.html#range
- // For car, ignore the dp limitation. It's physically impossible to rotate the car's screen
- // so if the orientation is forced, we need to respect that no matter what.
- final boolean isCar = mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_AUTOMOTIVE);
- // For TV, it's usually 960dp x 540dp, ignore the size limitation.
- // so if the orientation is forced, we need to respect that no matter what.
- final boolean isTv = mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_LEANBACK);
- mForceDefaultOrientation = ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar || isTv) &&
- res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
- // For debug purposes the next line turns this feature off with:
- // $ adb shell setprop config.override_forced_orient true
- // $ adb shell wm size reset
- !"true".equals(SystemProperties.get("config.override_forced_orient"));
- }
-
/**
* @return whether the navigation bar can be hidden, e.g. the device has a
* navigation bar and touch exploration is not enabled
*/
private boolean canHideNavigationBar() {
- return mHasNavigationBar;
- }
-
- @Override
- public boolean isDefaultOrientationForced() {
- return mForceDefaultOrientation;
+ return mDefaultDisplayPolicy.hasNavigationBar();
}
public void updateSettings() {
@@ -2465,15 +2176,6 @@
.getBoolean(com.android.internal.R.bool.config_volumeHushGestureEnabled)) {
mRingerToggleChord = Settings.Secure.VOLUME_HUSH_OFF;
}
- // Configure rotation suggestions.
- int showRotationSuggestions = Settings.Secure.getIntForUser(resolver,
- Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
- Settings.Secure.SHOW_ROTATION_SUGGESTIONS_DEFAULT,
- UserHandle.USER_CURRENT);
- if (mShowRotationSuggestions != showRotationSuggestions) {
- mShowRotationSuggestions = showRotationSuggestions;
- updateOrientationListenerLp(); // Enable, disable the orientation listener
- }
// Configure wake gesture.
boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
@@ -2484,24 +2186,6 @@
updateWakeGestureListenerLp();
}
- // Configure rotation lock.
- int userRotation = Settings.System.getIntForUser(resolver,
- Settings.System.USER_ROTATION, Surface.ROTATION_0,
- UserHandle.USER_CURRENT);
- if (mUserRotation != userRotation) {
- mUserRotation = userRotation;
- updateRotation = true;
- }
- int userRotationMode = Settings.System.getIntForUser(resolver,
- Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
- WindowManagerPolicy.USER_ROTATION_FREE :
- WindowManagerPolicy.USER_ROTATION_LOCKED;
- if (mUserRotationMode != userRotationMode) {
- mUserRotationMode = userRotationMode;
- updateRotation = true;
- updateOrientationListenerLp();
- }
-
if (mSystemReady) {
int pointerLocation = Settings.System.getIntForUser(resolver,
Settings.System.POINTER_LOCATION, 0, UserHandle.USER_CURRENT);
@@ -2542,8 +2226,8 @@
}
private boolean shouldEnableWakeGestureLp() {
- return mWakeGestureEnabledSetting && !mAwake
- && (!mLidControlsSleep || mLidState != LID_CLOSED)
+ return mWakeGestureEnabledSetting && !mDefaultDisplayPolicy.isAwake()
+ && (!mLidControlsSleep || mDefaultDisplayPolicy.getLidState() != LID_CLOSED)
&& mWakeGestureListener.isSupported();
}
@@ -2583,24 +2267,6 @@
}
}
- private int readRotation(int resID) {
- try {
- int rotation = mContext.getResources().getInteger(resID);
- switch (rotation) {
- case 0:
- return Surface.ROTATION_0;
- case 90:
- return Surface.ROTATION_90;
- case 180:
- return Surface.ROTATION_180;
- case 270:
- return Surface.ROTATION_270;
- }
- } catch (Resources.NotFoundException e) {
- // fall through
- }
- return -1;
- }
/** {@inheritDoc} */
@Override
@@ -2829,7 +2495,7 @@
}
void readLidState() {
- mLidState = mWindowManagerFuncs.getLidState();
+ mDefaultDisplayPolicy.setLidState(mWindowManagerFuncs.getLidState());
}
private void readCameraLensCoverState() {
@@ -2837,11 +2503,12 @@
}
private boolean isHidden(int accessibilityMode) {
+ final int lidState = mDefaultDisplayPolicy.getLidState();
switch (accessibilityMode) {
case 1:
- return mLidState == LID_CLOSED;
+ return lidState == LID_CLOSED;
case 2:
- return mLidState == LID_OPEN;
+ return lidState == LID_OPEN;
default:
return false;
}
@@ -2873,53 +2540,62 @@
}
@Override
- public void onOverlayChangedLw() {
- onConfigurationChanged();
+ public void onOverlayChangedLw(DisplayContentInfo displayContentInfo) {
+ onConfigurationChanged(displayContentInfo);
}
@Override
- public void onConfigurationChanged() {
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo) {
+ final DisplayRotation displayRotation = displayContentInfo.getDisplayRotation();
// TODO(multi-display): Define policy for secondary displays.
- Context uiContext = getSystemUiContext();
- final Resources res = uiContext.getResources();
+ if (!displayRotation.isDefaultDisplay) {
+ return;
+ }
- mStatusBarHeightForRotation[mPortraitRotation] =
- mStatusBarHeightForRotation[mUpsideDownRotation] = res.getDimensionPixelSize(
+ final Context uiContext = getSystemUiContext();
+ final Resources res = uiContext.getResources();
+ final int portraitRotation = displayRotation.getPortraitRotation();
+ final int upsideDownRotation = displayRotation.getUpsideDownRotation();
+ final int landscapeRotation = displayRotation.getLandscapeRotation();
+ final int seascapeRotation = displayRotation.getSeascapeRotation();
+
+ mStatusBarHeightForRotation[portraitRotation] =
+ mStatusBarHeightForRotation[upsideDownRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height_portrait);
- mStatusBarHeightForRotation[mLandscapeRotation] =
- mStatusBarHeightForRotation[mSeascapeRotation] = res.getDimensionPixelSize(
+ mStatusBarHeightForRotation[landscapeRotation] =
+ mStatusBarHeightForRotation[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height_landscape);
// Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotationDefault[mPortraitRotation] =
- mNavigationBarHeightForRotationDefault[mUpsideDownRotation] =
+ mNavigationBarHeightForRotationDefault[portraitRotation] =
+ mNavigationBarHeightForRotationDefault[upsideDownRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height);
- mNavigationBarHeightForRotationDefault[mLandscapeRotation] =
- mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize(
+ mNavigationBarHeightForRotationDefault[landscapeRotation] =
+ mNavigationBarHeightForRotationDefault[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape);
// Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotationDefault[mPortraitRotation] =
- mNavigationBarWidthForRotationDefault[mUpsideDownRotation] =
- mNavigationBarWidthForRotationDefault[mLandscapeRotation] =
- mNavigationBarWidthForRotationDefault[mSeascapeRotation] =
+ mNavigationBarWidthForRotationDefault[portraitRotation] =
+ mNavigationBarWidthForRotationDefault[upsideDownRotation] =
+ mNavigationBarWidthForRotationDefault[landscapeRotation] =
+ mNavigationBarWidthForRotationDefault[seascapeRotation] =
res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width);
if (ALTERNATE_CAR_MODE_NAV_SIZE) {
// Height of the navigation bar when presented horizontally at bottom
- mNavigationBarHeightForRotationInCarMode[mPortraitRotation] =
- mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] =
+ mNavigationBarHeightForRotationInCarMode[portraitRotation] =
+ mNavigationBarHeightForRotationInCarMode[upsideDownRotation] =
res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_car_mode);
- mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] =
- mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize(
+ mNavigationBarHeightForRotationInCarMode[landscapeRotation] =
+ mNavigationBarHeightForRotationInCarMode[seascapeRotation] = res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode);
// Width of the navigation bar when presented vertically along one side
- mNavigationBarWidthForRotationInCarMode[mPortraitRotation] =
- mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] =
- mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] =
- mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] =
+ mNavigationBarWidthForRotationInCarMode[portraitRotation] =
+ mNavigationBarWidthForRotationInCarMode[upsideDownRotation] =
+ mNavigationBarWidthForRotationInCarMode[landscapeRotation] =
+ mNavigationBarWidthForRotationInCarMode[seascapeRotation] =
res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width_car_mode);
}
@@ -2948,10 +2624,10 @@
int displayId, DisplayCutout displayCutout) {
int width = fullWidth;
// TODO(multi-display): Support navigation bar on secondary displays.
- if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
+ if (displayId == DEFAULT_DISPLAY && mDefaultDisplayPolicy.hasNavigationBar()) {
// For a basic navigation bar, when we are in landscape mode we place
// the navigation bar to the side.
- if (mNavigationBarCanMove && fullWidth > fullHeight) {
+ if (mDefaultDisplayPolicy.navigationBarCanMove() && fullWidth > fullHeight) {
width -= getNavigationBarWidth(rotation, uiMode);
}
}
@@ -2974,10 +2650,10 @@
int displayId, DisplayCutout displayCutout) {
int height = fullHeight;
// TODO(multi-display): Support navigation bar on secondary displays.
- if (displayId == DEFAULT_DISPLAY && mHasNavigationBar) {
+ if (displayId == DEFAULT_DISPLAY && mDefaultDisplayPolicy.hasNavigationBar()) {
// For a basic navigation bar, when we are in portrait mode we place
// the navigation bar to the bottom.
- if (!mNavigationBarCanMove || fullWidth < fullHeight) {
+ if (!mDefaultDisplayPolicy.navigationBarCanMove() || fullWidth < fullHeight) {
height -= getNavigationBarHeight(rotation, uiMode);
}
}
@@ -3065,8 +2741,8 @@
// In that case, we want to continue hiding the IME until the windows have completed
// drawing. This way, we know that the IME can be safely shown since the other windows are
// now shown.
- final boolean hideIme =
- win.isInputMethodWindow() && (mAodShowing || !mWindowManagerDrawComplete);
+ final boolean hideIme = win.isInputMethodWindow()
+ && (mAodShowing || !mDefaultDisplayPolicy.isWindowManagerDrawComplete());
return (keyguardLocked && !allowWhenLocked && win.getDisplayId() == DEFAULT_DISPLAY)
|| hideDockDivider || hideIme;
}
@@ -3444,7 +3120,7 @@
@Override
public void selectRotationAnimationLw(int anim[]) {
// If the screen is off or non-interactive, force a jumpcut.
- final boolean forceJumpcut = !mScreenOnFully || !okToAnimate();
+ final boolean forceJumpcut = !mDefaultDisplayPolicy.isScreenOnFully() || !okToAnimate();
if (PRINT_ANIM) Slog.i(TAG, "selectRotationAnimation mTopFullscreen="
+ mTopFullscreenOpaqueWindowState + " rotationAnimation="
+ (mTopFullscreenOpaqueWindowState == null ?
@@ -3851,7 +3527,7 @@
// If the device is in VR mode and keys are "internal" (e.g. on the side of the
// device), then drop the volume keys and don't forward it to the application/dispatch
// the audio event.
- if (mPersistentVrModeEnabled) {
+ if (mDefaultDisplayPolicy.isPersistentVrModeEnabled()) {
final InputDevice d = event.getDevice();
if (d != null && !d.isExternal()) {
return -1;
@@ -4391,17 +4067,9 @@
if (isKeyguardShowingAndNotOccluded()) {
// don't launch home if keyguard showing
return;
- } else if (mKeyguardOccluded && mKeyguardDelegate.isShowing()) {
- mKeyguardDelegate.dismiss(new KeyguardDismissCallback() {
- @Override
- public void onDismissSucceeded() throws RemoteException {
- mHandler.post(() -> {
- startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);
- });
- }
- }, null /* message */);
- return;
- } else if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) {
+ }
+
+ if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) {
// when in keyguard restricted mode, must first verify unlock
// before launching home
mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
@@ -4949,7 +4617,7 @@
@NavigationBarPosition
private int navigationBarPosition(int displayWidth, int displayHeight, int displayRotation) {
- if (mNavigationBarCanMove && displayWidth > displayHeight) {
+ if (mDefaultDisplayPolicy.navigationBarCanMove() && displayWidth > displayHeight) {
if (displayRotation == Surface.ROTATION_270) {
return NAV_BAR_LEFT;
} else {
@@ -5083,7 +4751,7 @@
mWindowFrames.setParentFrameWasClippedByDisplayCutout(false);
mWindowFrames.setDisplayCutout(displayFrames.mDisplayCutout);
- final boolean hasNavBar = (isDefaultDisplay && mHasNavigationBar
+ final boolean hasNavBar = (isDefaultDisplay && mDefaultDisplayPolicy.hasNavigationBar()
&& mNavigationBar != null && mNavigationBar.isVisibleLw());
final int adjust = sim & SOFT_INPUT_MASK_ADJUST;
@@ -5892,11 +5560,11 @@
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
// lid changed state
final int newLidState = lidOpen ? LID_OPEN : LID_CLOSED;
- if (newLidState == mLidState) {
+ if (newLidState == mDefaultDisplayPolicy.getLidState()) {
return;
}
- mLidState = newLidState;
+ mDefaultDisplayPolicy.setLidState(newLidState);
applyLidSwitchState();
updateRotation(true);
@@ -5931,17 +5599,6 @@
mCameraLensCoverState = lensCoverState;
}
- void setHdmiPlugged(boolean plugged) {
- if (mHdmiPlugged != plugged) {
- mHdmiPlugged = plugged;
- updateRotation(true, true);
- Intent intent = new Intent(ACTION_HDMI_PLUGGED);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
- mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
- }
- }
-
void initializeHdmiState() {
final int oldMask = StrictMode.allowThreadDiskReadsMask();
try {
@@ -5981,8 +5638,7 @@
}
// This dance forces the code in setHdmiPlugged to run.
// Always do this so the sticky intent is stuck (to false) if there is no hdmi.
- mHdmiPlugged = !plugged;
- setHdmiPlugged(!mHdmiPlugged);
+ mDefaultDisplayPolicy.setHdmiPlugged(plugged, true /* force */);
}
@@ -6422,16 +6078,6 @@
}
/**
- * Notify the StatusBar that system rotation suggestion has changed.
- */
- private void sendProposedRotationChangeToStatusBarInternal(int rotation, boolean isValid) {
- StatusBarManagerInternal statusBar = getStatusBarManagerInternal();
- if (statusBar != null) {
- statusBar.onProposedRotationChanged(rotation, isValid);
- }
- }
-
- /**
* Returns true if the key can have global actions attached to it.
* We reserve all power management keys for the system since they require
* very careful handling.
@@ -6460,7 +6106,7 @@
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE:
- return mDockMode != Intent.EXTRA_DOCK_STATE_UNDOCKED;
+ return mDefaultDisplayPolicy.getDockMode() != Intent.EXTRA_DOCK_STATE_UNDOCKED;
// ignore media and camera keys
case KeyEvent.KEYCODE_MUTE:
@@ -6508,7 +6154,8 @@
}
private boolean shouldDispatchInputWhenNonInteractive(KeyEvent event) {
- final boolean displayOff = (mDisplay == null || mDisplay.getState() == STATE_OFF);
+ final boolean displayOff = (mDefaultDisplay == null
+ || mDefaultDisplay.getState() == STATE_OFF);
if (displayOff && !mHasFeatureWatch) {
return false;
@@ -6658,8 +6305,8 @@
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
- mDockMode = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
- Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ mDefaultDisplayPolicy.setDockMode(intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+ Intent.EXTRA_DOCK_STATE_UNDOCKED));
} else {
try {
IUiModeManager uiModeService = IUiModeManager.Stub.asInterface(
@@ -6669,9 +6316,7 @@
}
}
updateRotation(true);
- synchronized (mLock) {
- updateOrientationListenerLp();
- }
+ mDefaultDisplayRotation.updateOrientationListener();
}
};
@@ -6699,6 +6344,7 @@
// and then updates our own bookkeeping based on the now-
// current user.
mSettingsObserver.onChange(false);
+ mDefaultDisplayRotation.onUserSwitch();
// force a re-application of focused window sysui visibility.
// the window may never have been shown for this user
@@ -6772,15 +6418,16 @@
mGoingToSleep = false;
mRequestedOrGoingToSleep = false;
+ mDefaultDisplayPolicy.setAwake(false);
// We must get this work done here because the power manager will drop
// the wake lock and let the system suspend once this function returns.
synchronized (mLock) {
- mAwake = false;
updateWakeGestureListenerLp();
- updateOrientationListenerLp();
updateLockScreenTimeout();
}
+ mDefaultDisplayRotation.updateOrientationListener();
+
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onFinishedGoingToSleep(why,
mCameraGestureTriggeredDuringGoingToSleep);
@@ -6794,17 +6441,17 @@
EventLog.writeEvent(70000, 1);
if (DEBUG_WAKEUP) Slog.i(TAG, "Started waking up...");
+ mDefaultDisplayPolicy.setAwake(true);
+
// Since goToSleep performs these functions synchronously, we must
// do the same here. We cannot post this work to a handler because
// that might cause it to become reordered with respect to what
// may happen in a future call to goToSleep.
synchronized (mLock) {
- mAwake = true;
-
updateWakeGestureListenerLp();
- updateOrientationListenerLp();
updateLockScreenTimeout();
}
+ mDefaultDisplayRotation.updateOrientationListener();
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onStartedWakingUp();
@@ -6841,16 +6488,14 @@
}
private void finishKeyguardDrawn() {
- synchronized (mLock) {
- if (!mScreenOnEarly || mKeyguardDrawComplete) {
- return; // We are not awake yet or we have already informed of this event.
- }
+ if (!mDefaultDisplayPolicy.finishKeyguardDrawn()) {
+ return;
+ }
- mKeyguardDrawComplete = true;
+ synchronized (mLock) {
if (mKeyguardDelegate != null) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
}
- mWindowManagerDrawComplete = false;
}
// ... eventually calls finishWindowsDrawn which will finalize our screen turn on
@@ -6865,18 +6510,13 @@
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turned off...");
updateScreenOffSleepToken(true);
+ mDefaultDisplayPolicy.screenTurnedOff();
synchronized (mLock) {
- mScreenOnEarly = false;
- mScreenOnFully = false;
- mKeyguardDrawComplete = false;
- mWindowManagerDrawComplete = false;
- mScreenOnListener = null;
- updateOrientationListenerLp();
-
if (mKeyguardDelegate != null) {
mKeyguardDelegate.onScreenTurnedOff();
}
}
+ mDefaultDisplayRotation.updateOrientationListener();
reportScreenStateToVrManager(false);
}
@@ -6893,13 +6533,9 @@
if (DEBUG_WAKEUP) Slog.i(TAG, "Screen turning on...");
updateScreenOffSleepToken(false);
- synchronized (mLock) {
- mScreenOnEarly = true;
- mScreenOnFully = false;
- mKeyguardDrawComplete = false;
- mWindowManagerDrawComplete = false;
- mScreenOnListener = screenOnListener;
+ mDefaultDisplayPolicy.screenTurnedOn(screenOnListener);
+ synchronized (mLock) {
if (mKeyguardDelegate != null && mKeyguardDelegate.hasKeyguard()) {
mHandler.removeMessages(MSG_KEYGUARD_DRAWN_TIMEOUT);
mHandler.sendEmptyMessageDelayed(MSG_KEYGUARD_DRAWN_TIMEOUT,
@@ -6942,46 +6578,29 @@
}
private void finishWindowsDrawn() {
- synchronized (mLock) {
- if (!mScreenOnEarly || mWindowManagerDrawComplete) {
- return; // Screen is not turned on or we did already handle this case earlier.
- }
-
- mWindowManagerDrawComplete = true;
+ if (!mDefaultDisplayPolicy.finishWindowsDrawn()) {
+ return;
}
finishScreenTurningOn();
}
private void finishScreenTurningOn() {
- synchronized (mLock) {
- // We have just finished drawing screen content. Since the orientation listener
- // gets only installed when all windows are drawn, we try to install it again.
- updateOrientationListenerLp();
+ // We have just finished drawing screen content. Since the orientation listener
+ // gets only installed when all windows are drawn, we try to install it again.
+ mDefaultDisplayRotation.updateOrientationListener();
+
+ final ScreenOnListener listener = mDefaultDisplayPolicy.getScreenOnListener();
+ if (!mDefaultDisplayPolicy.finishScreenTurningOn()) {
+ return; // Spurious or not ready yet.
}
- final ScreenOnListener listener;
+
final boolean enableScreen;
+ final boolean awake = mDefaultDisplayPolicy.isAwake();
synchronized (mLock) {
- if (DEBUG_WAKEUP) Slog.d(TAG,
- "finishScreenTurningOn: mAwake=" + mAwake
- + ", mScreenOnEarly=" + mScreenOnEarly
- + ", mScreenOnFully=" + mScreenOnFully
- + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
- + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
-
- if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete
- || (mAwake && !mKeyguardDrawComplete)) {
- return; // spurious or not ready yet
- }
-
- if (DEBUG_WAKEUP) Slog.i(TAG, "Finished screen turning on...");
- listener = mScreenOnListener;
- mScreenOnListener = null;
- mScreenOnFully = true;
-
// Remember the first time we draw the keyguard so we know when we're done with
// the main part of booting and can enable the screen and hide boot messages.
- if (!mKeyguardDrawnOnce && mAwake) {
+ if (!mKeyguardDrawnOnce && awake) {
mKeyguardDrawnOnce = true;
enableScreen = true;
if (mBootMessageNeedsHiding) {
@@ -7022,14 +6641,12 @@
@Override
public boolean isScreenOn() {
- synchronized (mLock) {
- return mScreenOnEarly;
- }
+ return mDefaultDisplayPolicy.isScreenOnEarly();
}
@Override
public boolean okToAnimate() {
- return mAwake && !mGoingToSleep;
+ return mDefaultDisplayPolicy.isAwake() && !mGoingToSleep;
}
/** {@inheritDoc} */
@@ -7139,7 +6756,7 @@
outInsets.setEmpty();
// Only navigation bar
- if (mHasNavigationBar) {
+ if (mDefaultDisplayPolicy.hasNavigationBar()) {
int position = navigationBarPosition(displayWidth, displayHeight, displayRotation);
if (position == NAV_BAR_BOTTOM) {
outInsets.bottom = getNavigationBarHeight(displayRotation, mUiMode);
@@ -7173,7 +6790,8 @@
public boolean isDockSideAllowed(int dockSide, int originalDockSide, int displayWidth,
int displayHeight, int displayRotation) {
final int barPosition = navigationBarPosition(displayWidth, displayHeight, displayRotation);
- return isDockSideAllowed(dockSide, originalDockSide, barPosition, mNavigationBarCanMove);
+ return isDockSideAllowed(dockSide, originalDockSide, barPosition,
+ mDefaultDisplayPolicy.navigationBarCanMove());
}
@VisibleForTesting
@@ -7210,293 +6828,6 @@
}
@Override
- public int rotationForOrientationLw(int orientation, int lastRotation, boolean defaultDisplay) {
- if (false) {
- Slog.v(TAG, "rotationForOrientationLw(orient="
- + orientation + ", last=" + lastRotation
- + "); user=" + mUserRotation + " "
- + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
- ? "USER_ROTATION_LOCKED" : "")
- );
- }
-
- if (mForceDefaultOrientation) {
- return Surface.ROTATION_0;
- }
-
- synchronized (mLock) {
- int sensorRotation = mOrientationListener.getProposedRotation(); // may be -1
- if (sensorRotation < 0) {
- sensorRotation = lastRotation;
- }
-
- final int preferredRotation;
- if (!defaultDisplay) {
- // For secondary displays we ignore things like displays sensors, docking mode and
- // rotation lock, and always prefer a default rotation.
- preferredRotation = Surface.ROTATION_0;
- } else if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
- // Ignore sensor when lid switch is open and rotation is forced.
- preferredRotation = mLidOpenRotation;
- } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR
- && (mCarDockEnablesAccelerometer || mCarDockRotation >= 0)) {
- // Ignore sensor when in car dock unless explicitly enabled.
- // This case can override the behavior of NOSENSOR, and can also
- // enable 180 degree rotation while docked.
- preferredRotation = mCarDockEnablesAccelerometer
- ? sensorRotation : mCarDockRotation;
- } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
- && (mDeskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
- // Ignore sensor when in desk dock unless explicitly enabled.
- // This case can override the behavior of NOSENSOR, and can also
- // enable 180 degree rotation while docked.
- preferredRotation = mDeskDockEnablesAccelerometer
- ? sensorRotation : mDeskDockRotation;
- } else if (mHdmiPlugged && mDemoHdmiRotationLock) {
- // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.
- // Note that the dock orientation overrides the HDMI orientation.
- preferredRotation = mDemoHdmiRotation;
- } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
- && mUndockedHdmiRotation >= 0) {
- // Ignore sensor when plugged into HDMI and an undocked orientation has
- // been specified in the configuration (only for legacy devices without
- // full multi-display support).
- // Note that the dock orientation overrides the HDMI orientation.
- preferredRotation = mUndockedHdmiRotation;
- } else if (mDemoRotationLock) {
- // Ignore sensor when demo rotation lock is enabled.
- // Note that the dock orientation and HDMI rotation lock override this.
- preferredRotation = mDemoRotation;
- } else if (mPersistentVrModeEnabled) {
- // While in VR, apps always prefer a portrait rotation. This does not change
- // any apps that explicitly set landscape, but does cause sensors be ignored,
- // and ignored any orientation lock that the user has set (this conditional
- // should remain above the ORIENTATION_LOCKED conditional below).
- preferredRotation = mPortraitRotation;
- } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
- // Application just wants to remain locked in the last rotation.
- preferredRotation = lastRotation;
- } else if (!mSupportAutoRotation) {
- // If we don't support auto-rotation then bail out here and ignore
- // the sensor and any rotation lock settings.
- preferredRotation = -1;
- } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
- && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
- || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
- || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
- || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
- || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
- // Otherwise, use sensor only if requested by the application or enabled
- // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
- if (mAllowAllRotations < 0) {
- // Can't read this during init() because the context doesn't
- // have display metrics at that time so we cannot determine
- // tablet vs. phone then.
- mAllowAllRotations = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
- }
- if (sensorRotation != Surface.ROTATION_180
- || mAllowAllRotations == 1
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
- || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
- preferredRotation = sensorRotation;
- } else {
- preferredRotation = lastRotation;
- }
- } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
- && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
- // Apply rotation lock. Does not apply to NOSENSOR.
- // The idea is that the user rotation expresses a weak preference for the direction
- // of gravity and as NOSENSOR is never affected by gravity, then neither should
- // NOSENSOR be affected by rotation lock (although it will be affected by docks).
- preferredRotation = mUserRotation;
- } else {
- // No overriding preference.
- // We will do exactly what the application asked us to do.
- preferredRotation = -1;
- }
-
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- // Return portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mPortraitRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- // Return landscape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- // Return reverse portrait unless overridden.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- return mUpsideDownRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- // Return seascape unless overridden.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- return mSeascapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- // Return either landscape rotation.
- if (isLandscapeOrSeascape(preferredRotation)) {
- return preferredRotation;
- }
- if (isLandscapeOrSeascape(lastRotation)) {
- return lastRotation;
- }
- return mLandscapeRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // Return either portrait rotation.
- if (isAnyPortrait(preferredRotation)) {
- return preferredRotation;
- }
- if (isAnyPortrait(lastRotation)) {
- return lastRotation;
- }
- return mPortraitRotation;
-
- default:
- // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
- // just return the preferred orientation we already calculated.
- if (preferredRotation >= 0) {
- return preferredRotation;
- }
- return Surface.ROTATION_0;
- }
- }
- }
-
- @Override
- public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
- return isAnyPortrait(rotation);
-
- case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
- return isLandscapeOrSeascape(rotation);
-
- default:
- return true;
- }
- }
-
- @Override
- public void setRotationLw(int rotation) {
- mOrientationListener.setCurrentRotation(rotation);
- }
-
- public boolean isRotationChoicePossible(int orientation) {
- // Rotation choice is only shown when the user is in locked mode.
- if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
-
- // We should only enable rotation choice if the rotation isn't forced by the lid, dock,
- // demo, hdmi, vr, etc mode
-
- // Determine if the rotation is currently forced
- if (mForceDefaultOrientation) {
- return false; // Rotation is forced to default orientation
-
- } else if (mLidState == LID_OPEN && mLidOpenRotation >= 0) {
- return false; // Rotation is forced mLidOpenRotation
-
- } else if (mDockMode == Intent.EXTRA_DOCK_STATE_CAR && !mCarDockEnablesAccelerometer) {
- return false; // Rotation forced to mCarDockRotation
-
- } else if ((mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
- && !mDeskDockEnablesAccelerometer) {
- return false; // Rotation forced to mDeskDockRotation
-
- } else if (mHdmiPlugged && mDemoHdmiRotationLock) {
- return false; // Rotation forced to mDemoHdmiRotation
-
- } else if (mHdmiPlugged && mDockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
- && mUndockedHdmiRotation >= 0) {
- return false; // Rotation forced to mUndockedHdmiRotation
-
- } else if (mDemoRotationLock) {
- return false; // Rotation forced to mDemoRotation
-
- } else if (mPersistentVrModeEnabled) {
- return false; // Rotation forced to mPortraitRotation
-
- } else if (!mSupportAutoRotation) {
- return false;
- }
-
- // Ensure that some rotation choice is possible for the given orientation
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
- case ActivityInfo.SCREEN_ORIENTATION_USER:
- case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // NOSENSOR description is ambiguous, in reality WM ignores user choice
- return true;
- }
-
- // Rotation is forced, should be controlled by system
- return false;
- }
-
- public boolean isValidRotationChoice(int orientation, final int preferredRotation) {
- // Determine if the given app orientation is compatible with the provided rotation choice
- switch (orientation) {
- case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
- // Works with any of the 4 rotations
- return preferredRotation >= 0;
-
- case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
- // It's possible for the user pref to be set at 180 because of FULL_USER. This would
- // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
- // but never to go to 180.
- return preferredRotation == mPortraitRotation;
-
- case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
- // Works landscape or seascape
- return isLandscapeOrSeascape(preferredRotation);
-
- case ActivityInfo.SCREEN_ORIENTATION_USER:
- case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
- // Works with any rotation except upside down
- return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
- }
-
- return false;
- }
-
- private boolean isLandscapeOrSeascape(int rotation) {
- return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
- }
-
- private boolean isAnyPortrait(int rotation) {
- return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
- }
-
- @Override
public int getUserRotationMode() {
return Settings.System.getIntForUser(mContext.getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
@@ -7568,8 +6899,8 @@
readCameraLensCoverState();
updateUiMode();
+ mDefaultDisplayRotation.updateOrientationListener();
synchronized (mLock) {
- updateOrientationListenerLp();
mSystemReady = true;
mHandler.post(new Runnable() {
@Override
@@ -7607,9 +6938,7 @@
@Override
public boolean canDismissBootAnimation() {
- synchronized (mLock) {
- return mKeyguardDrawComplete;
- }
+ return mDefaultDisplayPolicy.isKeyguardDrawComplete();
}
ProgressDialog mBootMsgDialog = null;
@@ -7709,7 +7038,7 @@
}
}
- if (mAwake && mNotifyUserActivity) {
+ if (mDefaultDisplayPolicy.isAwake() && mNotifyUserActivity) {
mHandler.sendEmptyMessageDelayed(MSG_NOTIFY_USER_ACTIVITY,
USER_ACTIVITY_NOTIFICATION_DELAY);
mNotifyUserActivity = false;
@@ -7752,7 +7081,7 @@
private void updateLockScreenTimeout() {
synchronized (mScreenLockTimeout) {
- boolean enable = (mAllowLockscreenWhenOn && mAwake &&
+ final boolean enable = (mAllowLockscreenWhenOn && mDefaultDisplayPolicy.isAwake() &&
mKeyguardDelegate != null && mKeyguardDelegate.isSecure(mCurrentUserId));
if (mLockScreenTimerActive != enable) {
if (enable) {
@@ -7807,10 +7136,11 @@
}
private void applyLidSwitchState() {
- if (mLidState == LID_CLOSED && mLidControlsSleep) {
+ final int lidState = mDefaultDisplayPolicy.getLidState();
+ if (lidState == LID_CLOSED && mLidControlsSleep) {
goToSleep(SystemClock.uptimeMillis(), PowerManager.GO_TO_SLEEP_REASON_LID_SWITCH,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
- } else if (mLidState == LID_CLOSED && mLidControlsScreenLock) {
+ } else if (lidState == LID_CLOSED && mLidControlsScreenLock) {
mWindowManagerFuncs.lockDeviceNow();
}
@@ -7832,17 +7162,8 @@
void updateRotation(boolean alwaysSendConfiguration) {
try {
- //set orientation on WindowManager
- mWindowManager.updateRotation(alwaysSendConfiguration, false);
- } catch (RemoteException e) {
- // Ignore
- }
- }
-
- void updateRotation(boolean alwaysSendConfiguration, boolean forceRelayout) {
- try {
- //set orientation on WindowManager
- mWindowManager.updateRotation(alwaysSendConfiguration, forceRelayout);
+ // Set orientation on WindowManager.
+ mWindowManager.updateRotation(alwaysSendConfiguration, false /* forceRelayout */);
} catch (RemoteException e) {
// Ignore
}
@@ -7875,12 +7196,14 @@
if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
intent = mDeskDockIntent;
}
- } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH
- && (mDockMode == Intent.EXTRA_DOCK_STATE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_HE_DESK
- || mDockMode == Intent.EXTRA_DOCK_STATE_LE_DESK)) {
- // Always launch dock home from home when watch is docked, if it exists.
- intent = mDeskDockIntent;
+ } else if (mUiMode == Configuration.UI_MODE_TYPE_WATCH) {
+ final int dockMode = mDefaultDisplayPolicy.getDockMode();
+ if (dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK) {
+ // Always launch dock home from home when watch is docked, if it exists.
+ intent = mDeskDockIntent;
+ }
} else if (mUiMode == Configuration.UI_MODE_TYPE_VR_HEADSET) {
if (ENABLE_VR_HEADSET_HOME_CAPTURE) {
intent = mVrHeadsetHomeIntent;
@@ -7995,16 +7318,6 @@
return true;
}
- @Override
- public void setCurrentOrientationLw(int newOrientation) {
- synchronized (mLock) {
- if (newOrientation != mCurrentAppOrientation) {
- mCurrentAppOrientation = newOrientation;
- updateOrientationListenerLp();
- }
- }
- }
-
private boolean isTheaterModeEnabled() {
return Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0) == 1;
@@ -8331,7 +7644,8 @@
final long now = SystemClock.uptimeMillis();
final boolean pendingPanic = mPendingPanicGestureUptime != 0
&& now - mPendingPanicGestureUptime <= PANIC_GESTURE_EXPIRATION;
- if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard() && mKeyguardDrawComplete) {
+ if (pendingPanic && hideNavBarSysui && !isStatusBarKeyguard()
+ && mDefaultDisplayPolicy.isKeyguardDrawComplete()) {
// The user performed the panic gesture recently, we're about to hide the bars,
// we're no longer on the Keyguard and the screen is ready. We can now request the bars.
mPendingPanicGestureUptime = 0;
@@ -8474,7 +7788,7 @@
// overridden by qemu.hw.mainkeys in the emulator.
@Override
public boolean hasNavigationBar() {
- return mHasNavigationBar;
+ return mDefaultDisplayPolicy.hasNavigationBar();
}
@Override
@@ -8519,19 +7833,21 @@
}
@Override
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
+ int newRotation) {
// For the upside down rotation we don't rotate seamlessly as the navigation
// bar moves position.
// Note most apps (using orientation:sensor or user as opposed to fullSensor)
// will not enter the reverse portrait orientation, so actually the
// orientation won't change at all.
- if (oldRotation == mUpsideDownRotation || newRotation == mUpsideDownRotation) {
+ if (oldRotation == displayRotation.getUpsideDownRotation()
+ || newRotation == displayRotation.getUpsideDownRotation()) {
return false;
}
// If the navigation bar can't change sides, then it will
// jump when we change orientations and we don't rotate
// seamlessly.
- if (!mNavigationBarCanMove) {
+ if (!displayRotation.getDisplayPolicy().navigationBarCanMove()) {
return false;
}
int delta = newRotation - oldRotation;
@@ -8565,12 +7881,13 @@
public void writeToProto(ProtoOutputStream proto, long fieldId) {
final long token = proto.start(fieldId);
proto.write(LAST_SYSTEM_UI_FLAGS, mLastSystemUiFlags);
- proto.write(ROTATION_MODE, mUserRotationMode);
- proto.write(ROTATION, mUserRotation);
- proto.write(ORIENTATION, mCurrentAppOrientation);
- proto.write(SCREEN_ON_FULLY, mScreenOnFully);
- proto.write(KEYGUARD_DRAW_COMPLETE, mKeyguardDrawComplete);
- proto.write(WINDOW_MANAGER_DRAW_COMPLETE, mWindowManagerDrawComplete);
+ proto.write(ROTATION_MODE, mDefaultDisplayRotation.getUserRotationMode());
+ proto.write(ROTATION, mDefaultDisplayRotation.getUserRotation());
+ proto.write(ORIENTATION, mDefaultDisplayRotation.getCurrentAppOrientation());
+ proto.write(SCREEN_ON_FULLY, mDefaultDisplayPolicy.isScreenOnFully());
+ proto.write(KEYGUARD_DRAW_COMPLETE, mDefaultDisplayPolicy.isKeyguardDrawComplete());
+ proto.write(WINDOW_MANAGER_DRAW_COMPLETE,
+ mDefaultDisplayPolicy.isWindowManagerDrawComplete());
if (mFocusedApp != null) {
proto.write(FOCUSED_APP_TOKEN, mFocusedApp.toString());
}
@@ -8592,8 +7909,8 @@
proto.write(FORCE_STATUS_BAR_FROM_KEYGUARD, mForceStatusBarFromKeyguard);
mStatusBarController.writeToProto(proto, STATUS_BAR);
mNavigationBarController.writeToProto(proto, NAVIGATION_BAR);
- if (mOrientationListener != null) {
- mOrientationListener.writeToProto(proto, ORIENTATION_LISTENER);
+ if (mDefaultOrientationListener != null) {
+ mDefaultOrientationListener.writeToProto(proto, ORIENTATION_LISTENER);
}
if (mKeyguardDelegate != null) {
mKeyguardDelegate.writeToProto(proto, KEYGUARD_DELEGATE);
@@ -8606,13 +7923,8 @@
pw.print(prefix); pw.print("mSafeMode="); pw.print(mSafeMode);
pw.print(" mSystemReady="); pw.print(mSystemReady);
pw.print(" mSystemBooted="); pw.println(mSystemBooted);
- pw.print(prefix); pw.print("mLidState=");
- pw.print(WindowManagerFuncs.lidStateToString(mLidState));
- pw.print(" mLidOpenRotation=");
- pw.println(Surface.rotationToString(mLidOpenRotation));
pw.print(prefix); pw.print("mCameraLensCoverState=");
- pw.print(WindowManagerFuncs.cameraLensStateToString(mCameraLensCoverState));
- pw.print(" mHdmiPlugged="); pw.println(mHdmiPlugged);
+ pw.println(WindowManagerFuncs.cameraLensStateToString(mCameraLensCoverState));
if (mLastSystemUiFlags != 0 || mResettingSystemUiFlags != 0
|| mForceClearedSystemUiFlags != 0) {
pw.print(prefix); pw.print("mLastSystemUiFlags=0x");
@@ -8630,27 +7942,9 @@
pw.println(mWakeGestureEnabledSetting);
pw.print(prefix);
- pw.print("mSupportAutoRotation="); pw.print(mSupportAutoRotation);
- pw.print(" mOrientationSensorEnabled="); pw.println(mOrientationSensorEnabled);
- pw.print(prefix); pw.print("mUiMode="); pw.print(Configuration.uiModeToString(mUiMode));
- pw.print(" mDockMode="); pw.println(Intent.dockStateToString(mDockMode));
- pw.print(prefix); pw.print("mEnableCarDockHomeCapture=");
- pw.print(mEnableCarDockHomeCapture);
- pw.print(" mCarDockRotation=");
- pw.print(Surface.rotationToString(mCarDockRotation));
- pw.print(" mDeskDockRotation=");
- pw.println(Surface.rotationToString(mDeskDockRotation));
- pw.print(prefix); pw.print("mUserRotationMode=");
- pw.print(WindowManagerPolicy.userRotationModeToString(mUserRotationMode));
- pw.print(" mUserRotation="); pw.print(Surface.rotationToString(mUserRotation));
- pw.print(" mAllowAllRotations=");
- pw.println(allowAllRotationsToString(mAllowAllRotations));
- pw.print(prefix); pw.print("mCurrentAppOrientation=");
- pw.println(ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
- pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
- pw.print(mCarDockEnablesAccelerometer);
- pw.print(" mDeskDockEnablesAccelerometer=");
- pw.println(mDeskDockEnablesAccelerometer);
+ pw.print("mUiMode=");
+ pw.print(Configuration.uiModeToString(mUiMode));
+ pw.print("mEnableCarDockHomeCapture="); pw.println(mEnableCarDockHomeCapture);
pw.print(prefix); pw.print("mLidKeyboardAccessibility=");
pw.print(mLidKeyboardAccessibility);
pw.print(" mLidNavigationAccessibility="); pw.print(mLidNavigationAccessibility);
@@ -8700,12 +7994,6 @@
pw.print(" mEndcallBehavior=");
pw.println(endcallBehaviorToString(mEndcallBehavior));
pw.print(prefix); pw.print("mHomePressed="); pw.println(mHomePressed);
- pw.print(prefix);
- pw.print("mAwake="); pw.print(mAwake);
- pw.print("mScreenOnEarly="); pw.print(mScreenOnEarly);
- pw.print(" mScreenOnFully="); pw.println(mScreenOnFully);
- pw.print(prefix); pw.print("mKeyguardDrawComplete="); pw.print(mKeyguardDrawComplete);
- pw.print(" mWindowManagerDrawComplete="); pw.println(mWindowManagerDrawComplete);
pw.print(prefix); pw.print("mDockLayer="); pw.print(mDockLayer);
pw.print(" mStatusBarLayer="); pw.println(mStatusBarLayer);
pw.print(prefix); pw.print("mShowingDream="); pw.print(mShowingDream);
@@ -8760,19 +8048,6 @@
pw.print(prefix); pw.print("mAllowLockscreenWhenOn="); pw.print(mAllowLockscreenWhenOn);
pw.print(" mLockScreenTimeout="); pw.print(mLockScreenTimeout);
pw.print(" mLockScreenTimerActive="); pw.println(mLockScreenTimerActive);
- pw.print(prefix); pw.print("mLandscapeRotation=");
- pw.print(Surface.rotationToString(mLandscapeRotation));
- pw.print(" mSeascapeRotation=");
- pw.println(Surface.rotationToString(mSeascapeRotation));
- pw.print(prefix); pw.print("mPortraitRotation=");
- pw.print(Surface.rotationToString(mPortraitRotation));
- pw.print(" mUpsideDownRotation=");
- pw.println(Surface.rotationToString(mUpsideDownRotation));
- pw.print(prefix); pw.print("mDemoHdmiRotation=");
- pw.print(Surface.rotationToString(mDemoHdmiRotation));
- pw.print(" mDemoHdmiRotationLock="); pw.println(mDemoHdmiRotationLock);
- pw.print(prefix); pw.print("mUndockedHdmiRotation=");
- pw.println(Surface.rotationToString(mUndockedHdmiRotation));
if (mHasFeatureLeanback) {
pw.print(prefix);
pw.print("mAccessibilityTvKey1Pressed="); pw.println(mAccessibilityTvKey1Pressed);
@@ -8790,8 +8065,8 @@
if (mWakeGestureListener != null) {
mWakeGestureListener.dump(pw, prefix);
}
- if (mOrientationListener != null) {
- mOrientationListener.dump(pw, prefix);
+ if (mDefaultOrientationListener != null) {
+ mDefaultOrientationListener.dump(pw, prefix);
}
if (mBurnInProtectionHelper != null) {
mBurnInProtectionHelper.dump(prefix, pw);
@@ -8804,19 +8079,6 @@
mHandler.getLooper().dump(new PrintWriterPrinter(pw), prefix + " ");
}
- private static String allowAllRotationsToString(int allowAll) {
- switch (allowAll) {
- case -1:
- return "unknown";
- case 0:
- return "false";
- case 1:
- return "true";
- default:
- return Integer.toString(allowAll);
- }
- }
-
private static String endcallBehaviorToString(int behavior) {
StringBuilder sb = new StringBuilder();
if ((behavior & Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0 ) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 0060328..cc39217 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -93,6 +93,7 @@
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.DisplayRotation;
import com.android.server.wm.WindowFrames;
import com.android.server.wm.utils.WmDisplayCutout;
@@ -177,7 +178,7 @@
/**
* Called when the resource overlays change.
*/
- default void onOverlayChangedLw() {}
+ default void onOverlayChangedLw(DisplayContentInfo displayContentInfo) {}
/**
* Interface to the Window Manager state associated with a particular
@@ -638,6 +639,27 @@
* The keyguard showing state has changed
*/
void onKeyguardShowingAndNotOccludedChanged();
+
+ DisplayContentInfo getDefaultDisplayContentInfo();
+ }
+
+ /**
+ * Provides the rotation of a device.
+ *
+ * @see com.android.server.policy.WindowOrientationListener
+ */
+ public interface RotationSource {
+ int getProposedRotation();
+
+ void setCurrentRotation(int rotation);
+ }
+
+ /**
+ * Interface to get public information of a display content.
+ */
+ public interface DisplayContentInfo {
+ DisplayRotation getDisplayRotation();
+ Display getDisplay();
}
/** Window has been added to the screen. */
@@ -669,6 +691,11 @@
public final int USER_ROTATION_LOCKED = 1;
/**
+ * Set the default display content to provide basic functions for the policy.
+ */
+ public void setDefaultDisplay(DisplayContentInfo displayContentInfo);
+
+ /**
* Perform initialization of the policy.
*
* @param context The system context we are running in.
@@ -677,17 +704,6 @@
WindowManagerFuncs windowManagerFuncs);
/**
- * @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true.
- */
- public boolean isDefaultOrientationForced();
-
- /**
- * Called by window manager once it has the initial, default native
- * display dimensions.
- */
- public void setInitialDisplaySize(Display display, int width, int height, int density);
-
- /**
* Check permissions when adding a window.
*
* @param attrs The window's LayoutParams.
@@ -1410,44 +1426,6 @@
public boolean isShowingDreamLw();
/**
- * Given an orientation constant, returns the appropriate surface rotation,
- * taking into account sensors, docking mode, rotation lock, and other factors.
- *
- * @param orientation An orientation constant, such as
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
- * @param lastRotation The most recently used rotation.
- * @param defaultDisplay Flag indicating whether the rotation is computed for the default
- * display. Currently for all non-default displays sensors, docking mode,
- * rotation lock and other factors are ignored.
- * @return The surface rotation to use.
- */
- public int rotationForOrientationLw(@ActivityInfo.ScreenOrientation int orientation,
- int lastRotation, boolean defaultDisplay);
-
- /**
- * Given an orientation constant and a rotation, returns true if the rotation
- * has compatible metrics to the requested orientation. For example, if
- * the application requested landscape and got seascape, then the rotation
- * has compatible metrics; if the application requested portrait and got landscape,
- * then the rotation has incompatible metrics; if the application did not specify
- * a preference, then anything goes.
- *
- * @param orientation An orientation constant, such as
- * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
- * @param rotation The rotation to check.
- * @return True if the rotation is compatible with the requested orientation.
- */
- public boolean rotationHasCompatibleMetricsLw(@ActivityInfo.ScreenOrientation int orientation,
- int rotation);
-
- /**
- * Called by the window manager when the rotation changes.
- *
- * @param rotation The new rotation.
- */
- public void setRotationLw(int rotation);
-
- /**
* Called when the system is mostly done booting to set whether
* the system should go into safe mode.
*/
@@ -1487,8 +1465,6 @@
*/
public void enableScreenAfterBoot();
- public void setCurrentOrientationLw(@ActivityInfo.ScreenOrientation int newOrientation);
-
/**
* Call from application to perform haptic feedback on its window.
*/
@@ -1702,9 +1678,10 @@
/**
* Called when the configuration has changed, and it's safe to load new values from resources.
*/
- public void onConfigurationChanged();
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo);
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation);
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation,
+ int oldRotation, int newRotation);
/**
* Called when System UI has been started.
diff --git a/services/core/java/com/android/server/policy/WindowOrientationListener.java b/services/core/java/com/android/server/policy/WindowOrientationListener.java
index 1508c9e..d5adb5e 100644
--- a/services/core/java/com/android/server/policy/WindowOrientationListener.java
+++ b/services/core/java/com/android/server/policy/WindowOrientationListener.java
@@ -204,6 +204,10 @@
}
}
+ public Handler getHandler() {
+ return mHandler;
+ }
+
/**
* Sets the current rotation.
*
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index d445611..b4dafc9 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -585,9 +585,9 @@
}
/**
- * Called when wireless charging has started so as to provide user feedback (sound and visual).
+ * Called when wireless charging has started - to provide user feedback (sound and visual).
*/
- public void onWirelessChargingStarted(int batteryLevel) {
+ public void onWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) {
if (DEBUG) {
Slog.d(TAG, "onWirelessChargingStarted");
}
@@ -596,13 +596,14 @@
Message msg = mHandler.obtainMessage(MSG_WIRELESS_CHARGING_STARTED);
msg.setAsynchronous(true);
msg.arg1 = batteryLevel;
+ msg.arg2 = userId;
mHandler.sendMessage(msg);
}
/**
- * Called when wired charging has started so as to provide user feedback
+ * Called when wired charging has started - to provide user feedback
*/
- public void onWiredChargingStarted() {
+ public void onWiredChargingStarted(@UserIdInt int userId) {
if (DEBUG) {
Slog.d(TAG, "onWiredChargingStarted");
}
@@ -610,6 +611,7 @@
mSuspendBlocker.acquire();
Message msg = mHandler.obtainMessage(MSG_WIRED_CHARGING_STARTED);
msg.setAsynchronous(true);
+ msg.arg1 = userId;
mHandler.sendMessage(msg);
}
@@ -748,10 +750,10 @@
/**
* Plays the wireless charging sound for both wireless and non-wireless charging
*/
- private void playChargingStartedSound() {
+ private void playChargingStartedSound(@UserIdInt int userId) {
final String soundPath = Settings.Global.getString(mContext.getContentResolver(),
Settings.Global.CHARGING_STARTED_SOUND);
- if (isChargingFeedbackEnabled() && soundPath != null) {
+ if (isChargingFeedbackEnabled(userId) && soundPath != null) {
final Uri soundUri = Uri.parse("file://" + soundPath);
if (soundUri != null) {
final Ringtone sfx = RingtoneManager.getRingtone(mContext, soundUri);
@@ -763,17 +765,17 @@
}
}
- private void showWirelessChargingStarted(int batteryLevel) {
- playWirelessChargingVibration();
- playChargingStartedSound();
+ private void showWirelessChargingStarted(int batteryLevel, @UserIdInt int userId) {
+ playWirelessChargingVibration(userId);
+ playChargingStartedSound(userId);
if (mStatusBarManagerInternal != null) {
mStatusBarManagerInternal.showChargingAnimation(batteryLevel);
}
mSuspendBlocker.release();
}
- private void showWiredChargingStarted() {
- playChargingStartedSound();
+ private void showWiredChargingStarted(@UserIdInt int userId) {
+ playChargingStartedSound(userId);
mSuspendBlocker.release();
}
@@ -781,17 +783,17 @@
mTrustManager.setDeviceLockedForUser(userId, true /*locked*/);
}
- private void playWirelessChargingVibration() {
- final boolean vibrateEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.CHARGING_VIBRATION_ENABLED, 0) != 0;
- if (vibrateEnabled && isChargingFeedbackEnabled()) {
+ private void playWirelessChargingVibration(@UserIdInt int userId) {
+ final boolean vibrateEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.CHARGING_VIBRATION_ENABLED, 1, userId) != 0;
+ if (vibrateEnabled && isChargingFeedbackEnabled(userId)) {
mVibrator.vibrate(WIRELESS_CHARGING_VIBRATION_EFFECT, VIBRATION_ATTRIBUTES);
}
}
- private boolean isChargingFeedbackEnabled() {
- final boolean enabled = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.CHARGING_SOUNDS_ENABLED, 1) != 0;
+ private boolean isChargingFeedbackEnabled(@UserIdInt int userId) {
+ final boolean enabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.CHARGING_SOUNDS_ENABLED, 1, userId) != 0;
final boolean dndOff = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS)
== Settings.Global.ZEN_MODE_OFF;
@@ -813,7 +815,7 @@
sendNextBroadcast();
break;
case MSG_WIRELESS_CHARGING_STARTED:
- showWirelessChargingStarted(msg.arg1);
+ showWirelessChargingStarted(msg.arg1, msg.arg2);
break;
case MSG_SCREEN_BRIGHTNESS_BOOST_CHANGED:
sendBrightnessBoostChangedBroadcast();
@@ -822,7 +824,7 @@
lockProfile(msg.arg1);
break;
case MSG_WIRED_CHARGING_STARTED:
- showWiredChargingStarted();
+ showWiredChargingStarted(msg.arg1);
break;
}
}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 9468dd7..13800b6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1705,9 +1705,9 @@
if (mBootCompleted) {
if (mIsPowered && !BatteryManager.isPlugWired(oldPlugType)
&& BatteryManager.isPlugWired(mPlugType)) {
- mNotifier.onWiredChargingStarted();
+ mNotifier.onWiredChargingStarted(mForegroundProfile);
} else if (dockedOnWirelessCharger) {
- mNotifier.onWirelessChargingStarted(mBatteryLevel);
+ mNotifier.onWirelessChargingStarted(mBatteryLevel, mForegroundProfile);
}
}
}
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index d6ccf3b..556038f 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -328,6 +328,7 @@
PackageManager pm = context.getPackageManager();
String app = intent.getData().getSchemeSpecificPart();
sStatsd.informOnePackageRemoved(app, uid);
+ StatsLog.write(StatsLog.GENERIC_ATOM, uid, 1000);
}
} else {
PackageManager pm = context.getPackageManager();
@@ -336,6 +337,7 @@
String app = intent.getData().getSchemeSpecificPart();
PackageInfo pi = pm.getPackageInfo(app, PackageManager.MATCH_ANY_USER);
sStatsd.informOnePackage(app, uid, pi.getLongVersionCode());
+ StatsLog.write(StatsLog.GENERIC_ATOM, uid, 1001);
}
} catch (Exception e) {
Slog.w(TAG, "Failed to inform statsd of an app update", e);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 738b0ca..519881e 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -547,50 +547,50 @@
}
@Override
- public void showFingerprintDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
+ public void showBiometricDialog(Bundle bundle, IBiometricPromptReceiver receiver) {
if (mBar != null) {
try {
- mBar.showFingerprintDialog(bundle, receiver);
+ mBar.showBiometricDialog(bundle, receiver);
} catch (RemoteException ex) {
}
}
}
@Override
- public void onFingerprintAuthenticated() {
+ public void onBiometricAuthenticated() {
if (mBar != null) {
try {
- mBar.onFingerprintAuthenticated();
+ mBar.onBiometricAuthenticated();
} catch (RemoteException ex) {
}
}
}
@Override
- public void onFingerprintHelp(String message) {
+ public void onBiometricHelp(String message) {
if (mBar != null) {
try {
- mBar.onFingerprintHelp(message);
+ mBar.onBiometricHelp(message);
} catch (RemoteException ex) {
}
}
}
@Override
- public void onFingerprintError(String error) {
+ public void onBiometricError(String error) {
if (mBar != null) {
try {
- mBar.onFingerprintError(error);
+ mBar.onBiometricError(error);
} catch (RemoteException ex) {
}
}
}
@Override
- public void hideFingerprintDialog() {
+ public void hideBiometricDialog() {
if (mBar != null) {
try {
- mBar.hideFingerprintDialog();
+ mBar.hideBiometricDialog();
} catch (RemoteException ex) {
}
}
diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java
index 8a135b8..3291a45 100644
--- a/services/core/java/com/android/server/trust/TrustManagerService.java
+++ b/services/core/java/com/android/server/trust/TrustManagerService.java
@@ -47,7 +47,6 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.storage.StorageManager;
import android.provider.Settings;
import android.service.trust.TrustAgentService;
import android.text.TextUtils;
@@ -61,7 +60,6 @@
import android.view.WindowManagerGlobal;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.content.PackageMonitor;
-import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.util.DumpUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.server.SystemService;
@@ -432,13 +430,20 @@
for (int i = 0; i < userInfos.size(); i++) {
UserInfo info = userInfos.get(i);
- if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
- || !info.supportsSwitchToByUser()) {
+ if (info == null || info.partial || !info.isEnabled() || info.guestToRemove) {
continue;
}
int id = info.id;
boolean secure = mLockPatternUtils.isSecure(id);
+
+ if (!info.supportsSwitchToByUser()) {
+ if (info.isManagedProfile() && !secure) {
+ setDeviceLockedForUser(id, false);
+ }
+ continue;
+ }
+
boolean trusted = aggregateIsTrusted(id);
boolean showingKeyguard = true;
boolean biometricAuthenticated = false;
@@ -993,7 +998,8 @@
enforceReportPermission();
final long identity = Binder.clearCallingIdentity();
try {
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
+ if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+ && mLockPatternUtils.isSecure(userId)) {
synchronized (mDeviceLockedForUser) {
mDeviceLockedForUser.put(userId, locked);
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 9d68c63..c8bd211 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -965,7 +965,7 @@
}
mPaddingChanged = false;
}
- if (mInfo != null && mInfo.getSupportsAmbientMode()) {
+ if (mInfo != null && mInfo.supportsAmbientMode()) {
try {
mEngine.setInAmbientMode(mInAmbientMode, false /* animated */);
} catch (RemoteException e) {
@@ -1777,7 +1777,7 @@
mInAmbientMode = inAmbienMode;
final WallpaperData data = mWallpaperMap.get(mCurrentUserId);
if (data != null && data.connection != null && data.connection.mInfo != null
- && data.connection.mInfo.getSupportsAmbientMode()) {
+ && data.connection.mInfo.supportsAmbientMode()) {
engine = data.connection.mEngine;
} else {
engine = null;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index bfecd9d..83075ed 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -274,4 +274,11 @@
public abstract void enableScreenAfterBoot(boolean booted);
public abstract boolean showStrictModeViolationDialog();
public abstract void showSystemReadyErrorDialogsIfNeeded();
+
+ public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason);
+ public abstract void onProcessMapped(int pid, WindowProcessController proc);
+ public abstract void onProcessUnMapped(int pid);
+
+ public abstract void onPackageDataCleared(String name);
+ public abstract void onPackageUninstalled(String name);
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 4b8b6074..b775918 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -78,6 +78,7 @@
import static com.android.server.wm.AppWindowTokenProto.STARTING_WINDOW;
import static com.android.server.wm.AppWindowTokenProto.THUMBNAIL;
import static com.android.server.wm.AppWindowTokenProto.WINDOW_TOKEN;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import android.annotation.CallSuper;
import android.app.Activity;
@@ -264,6 +265,12 @@
*/
private boolean mWillCloseOrEnterPip;
+ /** Layer used to constrain the animation to a token's stack bounds. */
+ SurfaceControl mAnimationBoundsLayer;
+
+ /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
+ boolean mNeedsAnimationBoundsLayer;
+
AppWindowToken(WindowManagerService service, IApplicationToken token, boolean voiceInteraction,
DisplayContent dc, long inputDispatchingTimeoutNanos, boolean fullscreen,
boolean showForAllUsers, int targetSdk, int orientation, int rotationAnimationHint,
@@ -1720,6 +1727,20 @@
return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
}
+ /**
+ * Creates a layer to apply crop to an animation.
+ */
+ private SurfaceControl createAnimationBoundsLayer(Transaction t) {
+ if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.i(TAG, "Creating animation bounds layer");
+ final SurfaceControl.Builder builder = makeAnimationLeash()
+ .setParent(getAnimationLeashParent())
+ .setName(getSurfaceControl() + " - animation-bounds")
+ .setSize(getSurfaceWidth(), getSurfaceHeight());
+ final SurfaceControl boundsLayer = builder.build();
+ t.show(boundsLayer);
+ return boundsLayer;
+ }
+
boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
boolean isVoiceInteraction) {
@@ -1753,12 +1774,15 @@
adapter = mService.mAppTransition.getRemoteAnimationController()
.createAnimationAdapter(this, mTmpPoint, mTmpRect);
} else {
+ final int appStackClipMode = mService.mAppTransition.getAppStackClipMode();
+ mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
+
final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
if (a != null) {
adapter = new LocalAnimationAdapter(
new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
mService.mAppTransition.canSkipFirstFrame(),
- mService.mAppTransition.getAppStackClipMode(),
+ appStackClipMode,
true /* isAppAnimation */),
mService.mSurfaceAnimationRunner);
if (a.getZAdjustment() == Animation.ZORDER_TOP) {
@@ -1858,6 +1882,11 @@
@Override
public void onAnimationLeashDestroyed(Transaction t) {
super.onAnimationLeashDestroyed(t);
+ if (mAnimationBoundsLayer != null) {
+ t.destroy(mAnimationBoundsLayer);
+ mAnimationBoundsLayer = null;
+ }
+
if (mAnimatingAppWindowTokenRegistry != null) {
mAnimatingAppWindowTokenRegistry.notifyFinished(this);
}
@@ -1908,6 +1937,26 @@
if (mAnimatingAppWindowTokenRegistry != null) {
mAnimatingAppWindowTokenRegistry.notifyStarting(this);
}
+
+ // If the animation needs to be cropped then an animation bounds layer is created as a child
+ // of the pinned stack or animation layer. The leash is then reparented to this new layer.
+ if (mNeedsAnimationBoundsLayer) {
+ final TaskStack stack = getStack();
+ if (stack == null) {
+ return;
+ }
+ mAnimationBoundsLayer = createAnimationBoundsLayer(t);
+
+ // Set clip rect to stack bounds.
+ mTmpRect.setEmpty();
+ stack.getBounds(mTmpRect);
+
+ // Crop to stack bounds.
+ t.setWindowCrop(mAnimationBoundsLayer, mTmpRect);
+
+ // Reparent leash to animation bounds layer.
+ t.reparent(leash, mAnimationBoundsLayer.getHandle());
+ }
}
/**
@@ -1927,6 +1976,7 @@
mTransit = TRANSIT_UNSET;
mTransitFlags = 0;
mNeedsZBoost = false;
+ mNeedsAnimationBoundsLayer = false;
setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM | FINISH_LAYOUT_REDO_WALLPAPER,
"AppWindowToken");
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index cea5f4c6..d7d5cf8 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -173,7 +173,8 @@
* IMPORTANT: No method from this class should ever be used without holding
* WindowManagerService.mWindowMap.
*/
-class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer> {
+class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowContainer>
+ implements WindowManagerPolicy.DisplayContentInfo {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayContent" : TAG_WM;
/** Unique identifier of this stack. */
@@ -234,6 +235,8 @@
private final DisplayInfo mDisplayInfo = new DisplayInfo();
private final Display mDisplay;
private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
+ private final DisplayPolicy mDisplayPolicy;
+ private DisplayRotation mDisplayRotation;
DisplayFrames mDisplayFrames;
/**
@@ -304,8 +307,11 @@
private boolean mLayoutNeeded;
int pendingLayoutChanges;
int mDeferredRotationPauseCount;
+
// TODO(multi-display): remove some of the usages.
+ @VisibleForTesting
boolean isDefaultDisplay;
+
/**
* Flag indicating whether WindowManager should override info for this display in
* DisplayManager.
@@ -762,6 +768,13 @@
mDisplayFrames = new DisplayFrames(mDisplayId, mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
initializeDisplayBaseInfo();
+ mDisplayPolicy = new DisplayPolicy(service);
+ mDisplayRotation = new DisplayRotation(service, this);
+ if (isDefaultDisplay) {
+ // The policy may be invoked right after here, so it requires the necessary default
+ // fields of this display content.
+ mService.mPolicy.setDefaultDisplay(this);
+ }
mDividerControllerLocked = new DockedStackDividerController(service, this);
mPinnedStackControllerLocked = new PinnedStackController(service, this);
@@ -801,7 +814,9 @@
// {@link DisplayContent} ready for use.
mDisplayReady = true;
- mInputMonitor = new InputMonitor(service, mDisplayId);
+ // TODO(b/112081256): Use independent InputMonitor.
+ mInputMonitor = isDefaultDisplay ? new InputMonitor(service, mDisplayId)
+ : mService.getDefaultDisplayContentLocked().mInputMonitor;
}
boolean isReady() {
@@ -905,7 +920,8 @@
appToken.onRemovedFromDisplay();
}
- Display getDisplay() {
+ @Override
+ public Display getDisplay() {
return mDisplay;
}
@@ -917,6 +933,20 @@
return mDisplayMetrics;
}
+ DisplayPolicy getDisplayPolicy() {
+ return mDisplayPolicy;
+ }
+
+ @Override
+ public DisplayRotation getDisplayRotation() {
+ return mDisplayRotation;
+ }
+
+ @VisibleForTesting
+ void setDisplayRotation(DisplayRotation displayRotation) {
+ mDisplayRotation = displayRotation;
+ }
+
int getRotation() {
return mRotation;
}
@@ -924,6 +954,7 @@
@VisibleForTesting
void setRotation(int newRotation) {
mRotation = newRotation;
+ mDisplayRotation.setRotation(newRotation);
}
int getLastOrientation() {
@@ -969,14 +1000,45 @@
mDeferredRotationPauseCount--;
if (mDeferredRotationPauseCount == 0) {
- final boolean changed = updateRotationUnchecked();
- if (changed) {
- mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
- }
+ updateRotationAndSendNewConfigIfNeeded();
}
}
/**
+ * If this is true we have updated our desired orientation, but not yet changed the real
+ * orientation our applied our screen rotation animation. For example, because a previous
+ * screen rotation was in progress.
+ *
+ * @return {@code true} if the there is an ongoing rotation change.
+ */
+ boolean rotationNeedsUpdate() {
+ final int lastOrientation = getLastOrientation();
+ final int oldRotation = getRotation();
+ final boolean oldAltOrientation = getAltOrientation();
+
+ final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
+ final boolean altOrientation = !mDisplayRotation.rotationHasCompatibleMetrics(
+ lastOrientation, rotation);
+ if (oldRotation == rotation && oldAltOrientation == altOrientation) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Update rotation of the display and send configuration if the rotation is changed.
+ *
+ * @return {@code true} if the rotation has been changed and the new config is sent.
+ */
+ boolean updateRotationAndSendNewConfigIfNeeded() {
+ final boolean changed = updateRotationUnchecked(false /* forceUpdate */);
+ if (changed) {
+ mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, mDisplayId).sendToTarget();
+ }
+ return changed;
+ }
+
+ /**
* Update rotation of the display.
*
* @return {@code true} if the rotation has been changed. In this case YOU MUST CALL
@@ -1034,13 +1096,12 @@
final int oldRotation = mRotation;
final int lastOrientation = mLastOrientation;
final boolean oldAltOrientation = mAltOrientation;
- final int rotation = mService.mPolicy.rotationForOrientationLw(lastOrientation, oldRotation,
- isDefaultDisplay);
+ final int rotation = mDisplayRotation.rotationForOrientation(lastOrientation, oldRotation);
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Computed rotation=" + rotation + " for display id="
+ mDisplayId + " based on lastOrientation=" + lastOrientation
+ " and oldRotation=" + oldRotation);
- boolean mayRotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(oldRotation,
- rotation);
+ boolean mayRotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(mDisplayRotation,
+ oldRotation, rotation);
if (mayRotateSeamlessly) {
final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
@@ -1071,7 +1132,7 @@
// an orientation that has different metrics than it expected.
// eg. Portrait instead of Landscape.
- final boolean altOrientation = !mService.mPolicy.rotationHasCompatibleMetricsLw(
+ final boolean altOrientation = !mDisplayRotation.rotationHasCompatibleMetrics(
lastOrientation, rotation);
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Display id=" + mDisplayId
@@ -1093,11 +1154,8 @@
mService.mWaitingForConfig = true;
}
- mRotation = rotation;
+ setRotation(rotation);
mAltOrientation = altOrientation;
- if (isDefaultDisplay) {
- mService.mPolicy.setRotationLw(rotation);
- }
mService.mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_ACTIVE;
mService.mH.sendNewMessageDelayed(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT,
@@ -1191,8 +1249,23 @@
}
void configureDisplayPolicy() {
- mService.mPolicy.setInitialDisplaySize(getDisplay(),
- mBaseDisplayWidth, mBaseDisplayHeight, mBaseDisplayDensity);
+ final int width = mBaseDisplayWidth;
+ final int height = mBaseDisplayHeight;
+ final int shortSize;
+ final int longSize;
+ if (width > height) {
+ shortSize = height;
+ longSize = width;
+ } else {
+ shortSize = width;
+ longSize = height;
+ }
+
+ final int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
+ final int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / mBaseDisplayDensity;
+
+ mDisplayRotation.configure(width, height, shortSizeDp, longSizeDp);
+ mDisplayPolicy.configure(width, height, shortSizeDp);
mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
@@ -1931,8 +2004,8 @@
getParent().positionChildAt(position, this, includingParents);
}
- void positionStackAt(int position, TaskStack child) {
- mTaskStackContainers.positionChildAt(position, child, false /* includingParents */);
+ void positionStackAt(int position, TaskStack child, boolean includingParents) {
+ mTaskStackContainers.positionChildAt(position, child, includingParents);
layoutAndAssignWindowLayersIfNeeded();
}
@@ -2367,6 +2440,10 @@
pw.println();
mDisplayFrames.dump(prefix, pw);
pw.println();
+ mDisplayPolicy.dump(prefix, pw);
+ pw.println();
+ mDisplayRotation.dump(prefix, pw);
+ pw.println();
mInputMonitor.dump(pw, " ");
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
new file mode 100644
index 0000000..9151ddf
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManagerPolicyConstants.ACTION_HDMI_PLUGGED;
+import static android.view.WindowManagerPolicyConstants.EXTRA_HDMI_PLUGGED_STATE;
+import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_ABSENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.content.Intent;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.server.policy.WindowManagerPolicy.ScreenOnListener;
+import com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs;
+
+import java.io.PrintWriter;
+
+/**
+ * The policy that provides the basic behaviors and states of a display to show UI.
+ */
+public class DisplayPolicy {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayPolicy" : TAG_WM;
+
+ private final WindowManagerService mService;
+ private final Object mLock;
+
+ private final boolean mCarDockEnablesAccelerometer;
+ private final boolean mDeskDockEnablesAccelerometer;
+
+ private volatile int mLidState = LID_ABSENT;
+ private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
+ private volatile boolean mHdmiPlugged;
+
+ private volatile boolean mHasNavigationBar;
+ // Can the navigation bar ever move to the side?
+ private volatile boolean mNavigationBarCanMove;
+
+ // Written by vr manager thread, only read in this class.
+ private volatile boolean mPersistentVrModeEnabled;
+
+ private volatile boolean mAwake;
+ private volatile boolean mScreenOnEarly;
+ private volatile boolean mScreenOnFully;
+ private volatile ScreenOnListener mScreenOnListener;
+
+ private volatile boolean mKeyguardDrawComplete;
+ private volatile boolean mWindowManagerDrawComplete;
+
+ DisplayPolicy(WindowManagerService service) {
+ mService = service;
+ mLock = service.getWindowManagerLock();
+ mCarDockEnablesAccelerometer = service.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_carDockEnablesAccelerometer);
+ mDeskDockEnablesAccelerometer = service.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_deskDockEnablesAccelerometer);
+ }
+
+ void configure(int width, int height, int shortSizeDp) {
+ // Allow the navigation bar to move on non-square small devices (phones).
+ mNavigationBarCanMove = width != height && shortSizeDp < 600;
+
+ mHasNavigationBar = mService.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_showNavigationBar);
+
+ // Allow a system property to override this. Used by the emulator.
+ // See also hasNavigationBar().
+ String navBarOverride = SystemProperties.get("qemu.hw.mainkeys");
+ if ("1".equals(navBarOverride)) {
+ mHasNavigationBar = false;
+ } else if ("0".equals(navBarOverride)) {
+ mHasNavigationBar = true;
+ }
+ }
+
+ public void setHdmiPlugged(boolean plugged) {
+ setHdmiPlugged(plugged, false /* force */);
+ }
+
+ public void setHdmiPlugged(boolean plugged, boolean force) {
+ if (force || mHdmiPlugged != plugged) {
+ mHdmiPlugged = plugged;
+ mService.updateRotation(true /* alwaysSendConfiguration */, true /* forceRelayout */);
+ final Intent intent = new Intent(ACTION_HDMI_PLUGGED);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ intent.putExtra(EXTRA_HDMI_PLUGGED_STATE, plugged);
+ mService.mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL);
+ }
+ }
+
+ boolean isHdmiPlugged() {
+ return mHdmiPlugged;
+ }
+
+ boolean isCarDockEnablesAccelerometer() {
+ return mCarDockEnablesAccelerometer;
+ }
+
+ boolean isDeskDockEnablesAccelerometer() {
+ return mDeskDockEnablesAccelerometer;
+ }
+
+ public void setPersistentVrModeEnabled(boolean persistentVrModeEnabled) {
+ mPersistentVrModeEnabled = persistentVrModeEnabled;
+ }
+
+ public boolean isPersistentVrModeEnabled() {
+ return mPersistentVrModeEnabled;
+ }
+
+ public void setDockMode(int dockMode) {
+ mDockMode = dockMode;
+ }
+
+ public int getDockMode() {
+ return mDockMode;
+ }
+
+ public boolean hasNavigationBar() {
+ return mHasNavigationBar;
+ }
+
+ public boolean navigationBarCanMove() {
+ return mNavigationBarCanMove;
+ }
+
+ public void setLidState(int lidState) {
+ mLidState = lidState;
+ }
+
+ public int getLidState() {
+ return mLidState;
+ }
+
+ public void setAwake(boolean awake) {
+ mAwake = awake;
+ }
+
+ public boolean isAwake() {
+ return mAwake;
+ }
+
+ public boolean isScreenOnEarly() {
+ return mScreenOnEarly;
+ }
+
+ public boolean isScreenOnFully() {
+ return mScreenOnFully;
+ }
+
+ public boolean isKeyguardDrawComplete() {
+ return mKeyguardDrawComplete;
+ }
+
+ public boolean isWindowManagerDrawComplete() {
+ return mWindowManagerDrawComplete;
+ }
+
+ public ScreenOnListener getScreenOnListener() {
+ return mScreenOnListener;
+ }
+
+ public void screenTurnedOn(ScreenOnListener screenOnListener) {
+ synchronized (mLock) {
+ mScreenOnEarly = true;
+ mScreenOnFully = false;
+ mKeyguardDrawComplete = false;
+ mWindowManagerDrawComplete = false;
+ mScreenOnListener = screenOnListener;
+ }
+ }
+
+ public void screenTurnedOff() {
+ synchronized (mLock) {
+ mScreenOnEarly = false;
+ mScreenOnFully = false;
+ mKeyguardDrawComplete = false;
+ mWindowManagerDrawComplete = false;
+ mScreenOnListener = null;
+ }
+ }
+
+ /** Return false if we are not awake yet or we have already informed of this event. */
+ public boolean finishKeyguardDrawn() {
+ synchronized (mLock) {
+ if (!mScreenOnEarly || mKeyguardDrawComplete) {
+ return false;
+ }
+
+ mKeyguardDrawComplete = true;
+ mWindowManagerDrawComplete = false;
+ }
+ return true;
+ }
+
+ /** Return false if screen is not turned on or we did already handle this case earlier. */
+ public boolean finishWindowsDrawn() {
+ synchronized (mLock) {
+ if (!mScreenOnEarly || mWindowManagerDrawComplete) {
+ return false;
+ }
+
+ mWindowManagerDrawComplete = true;
+ }
+ return true;
+ }
+
+ /** Return false if it is not ready to turn on. */
+ public boolean finishScreenTurningOn() {
+ synchronized (mLock) {
+ if (DEBUG_SCREEN_ON) Slog.d(TAG,
+ "finishScreenTurningOn: mAwake=" + mAwake
+ + ", mScreenOnEarly=" + mScreenOnEarly
+ + ", mScreenOnFully=" + mScreenOnFully
+ + ", mKeyguardDrawComplete=" + mKeyguardDrawComplete
+ + ", mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+
+ if (mScreenOnFully || !mScreenOnEarly || !mWindowManagerDrawComplete
+ || (mAwake && !mKeyguardDrawComplete)) {
+ return false;
+ }
+
+ if (DEBUG_SCREEN_ON) Slog.i(TAG, "Finished screen turning on...");
+ mScreenOnListener = null;
+ mScreenOnFully = true;
+ }
+ return true;
+ }
+
+ void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "DisplayPolicy");
+ pw.print(prefix + " mCarDockEnablesAccelerometer=" + mCarDockEnablesAccelerometer);
+ pw.println(" mDeskDockEnablesAccelerometer=" + mDeskDockEnablesAccelerometer);
+ pw.print(prefix + " mDockMode=" + Intent.dockStateToString(mDockMode));
+ pw.println(" mLidState=" + WindowManagerFuncs.lidStateToString(mLidState));
+ pw.print(prefix + " mAwake=" + mAwake);
+ pw.print(" mScreenOnEarly=" + mScreenOnEarly);
+ pw.println(" mScreenOnFully=" + mScreenOnFully);
+ pw.print(prefix + " mKeyguardDrawComplete=" + mKeyguardDrawComplete);
+ pw.println(" mWindowManagerDrawComplete=" + mWindowManagerDrawComplete);
+ pw.println(prefix + " mHdmiPlugged=" + mHdmiPlugged);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
new file mode 100644
index 0000000..685c444
--- /dev/null
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -0,0 +1,881 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.policy.WindowManagerPolicy.WindowManagerFuncs.LID_OPEN;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.database.ContentObserver;
+import android.hardware.power.V1_0.PowerHint;
+import android.os.Handler;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.Surface;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+import com.android.server.UiThread;
+import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.policy.WindowOrientationListener;
+import com.android.server.statusbar.StatusBarManagerInternal;
+
+import java.io.PrintWriter;
+
+/**
+ * Defines the mapping between orientation and rotation of a display.
+ * Non-public methods are assumed to run inside WM lock.
+ */
+public class DisplayRotation {
+ private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;
+
+ private final WindowManagerService mService;
+ private final DisplayPolicy mDisplayPolicy;
+ private final Context mContext;
+ private final Object mLock;
+
+ public final boolean isDefaultDisplay;
+ private final boolean mSupportAutoRotation;
+ private final int mLidOpenRotation;
+ private final int mCarDockRotation;
+ private final int mDeskDockRotation;
+ private final int mUndockedHdmiRotation;
+
+ private OrientationListener mOrientationListener;
+ private StatusBarManagerInternal mStatusBarManagerInternal;
+ private SettingsObserver mSettingsObserver;
+
+ // Default display does not rotate, apps that require non-default orientation will have to
+ // have the orientation emulated.
+ private boolean mForceDefaultOrientation;
+
+ private int mCurrentAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+
+ @VisibleForTesting
+ int mLandscapeRotation; // default landscape
+ @VisibleForTesting
+ int mSeascapeRotation; // "other" landscape, 180 degrees from mLandscapeRotation
+ @VisibleForTesting
+ int mPortraitRotation; // default portrait
+ @VisibleForTesting
+ int mUpsideDownRotation; // "other" portrait
+
+ // Behavior of rotation suggestions. (See Settings.Secure.SHOW_ROTATION_SUGGESTION)
+ private int mShowRotationSuggestions;
+
+ private int mAllowAllRotations = -1;
+ private int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+ private int mUserRotation = Surface.ROTATION_0;
+
+ private int mDemoHdmiRotation;
+ private int mDemoRotation;
+ private boolean mDemoHdmiRotationLock;
+ private boolean mDemoRotationLock;
+
+ DisplayRotation(WindowManagerService service, DisplayContent displayContent) {
+ this(service, displayContent, displayContent.getDisplayPolicy(),
+ service.mContext, service.getWindowManagerLock());
+ }
+
+ @VisibleForTesting
+ DisplayRotation(WindowManagerService service, DisplayContent displayContent,
+ DisplayPolicy displayPolicy, Context context, Object lock) {
+ mService = service;
+ mDisplayPolicy = displayPolicy;
+ mContext = context;
+ mLock = lock;
+ isDefaultDisplay = displayContent.isDefaultDisplay;
+
+ mSupportAutoRotation = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_supportAutoRotation);
+ mLidOpenRotation = readRotation(
+ com.android.internal.R.integer.config_lidOpenRotation);
+ mCarDockRotation = readRotation(
+ com.android.internal.R.integer.config_carDockRotation);
+ mDeskDockRotation = readRotation(
+ com.android.internal.R.integer.config_deskDockRotation);
+ mUndockedHdmiRotation = readRotation(
+ com.android.internal.R.integer.config_undockedHdmiRotation);
+
+ if (isDefaultDisplay) {
+ final Handler uiHandler = UiThread.getHandler();
+ mOrientationListener = new OrientationListener(mContext, uiHandler);
+ mOrientationListener.setCurrentRotation(displayContent.getRotation());
+ mSettingsObserver = new SettingsObserver(uiHandler);
+ mSettingsObserver.observe();
+ }
+ }
+
+ private int readRotation(int resID) {
+ try {
+ final int rotation = mContext.getResources().getInteger(resID);
+ switch (rotation) {
+ case 0:
+ return Surface.ROTATION_0;
+ case 90:
+ return Surface.ROTATION_90;
+ case 180:
+ return Surface.ROTATION_180;
+ case 270:
+ return Surface.ROTATION_270;
+ }
+ } catch (Resources.NotFoundException e) {
+ // fall through
+ }
+ return -1;
+ }
+
+ void configure(int width, int height, int shortSizeDp, int longSizeDp) {
+ final Resources res = mContext.getResources();
+ if (width > height) {
+ mLandscapeRotation = Surface.ROTATION_0;
+ mSeascapeRotation = Surface.ROTATION_180;
+ if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ mPortraitRotation = Surface.ROTATION_90;
+ mUpsideDownRotation = Surface.ROTATION_270;
+ } else {
+ mPortraitRotation = Surface.ROTATION_270;
+ mUpsideDownRotation = Surface.ROTATION_90;
+ }
+ } else {
+ mPortraitRotation = Surface.ROTATION_0;
+ mUpsideDownRotation = Surface.ROTATION_180;
+ if (res.getBoolean(com.android.internal.R.bool.config_reverseDefaultRotation)) {
+ mLandscapeRotation = Surface.ROTATION_270;
+ mSeascapeRotation = Surface.ROTATION_90;
+ } else {
+ mLandscapeRotation = Surface.ROTATION_90;
+ mSeascapeRotation = Surface.ROTATION_270;
+ }
+ }
+
+ // For demo purposes, allow the rotation of the HDMI display to be controlled.
+ // By default, HDMI locks rotation to landscape.
+ if ("portrait".equals(SystemProperties.get("persist.demo.hdmirotation"))) {
+ mDemoHdmiRotation = mPortraitRotation;
+ } else {
+ mDemoHdmiRotation = mLandscapeRotation;
+ }
+ mDemoHdmiRotationLock = SystemProperties.getBoolean("persist.demo.hdmirotationlock", false);
+
+ // For demo purposes, allow the rotation of the remote display to be controlled.
+ // By default, remote display locks rotation to landscape.
+ if ("portrait".equals(SystemProperties.get("persist.demo.remoterotation"))) {
+ mDemoRotation = mPortraitRotation;
+ } else {
+ mDemoRotation = mLandscapeRotation;
+ }
+ mDemoRotationLock = SystemProperties.getBoolean("persist.demo.rotationlock", false);
+
+ // Only force the default orientation if the screen is xlarge, at least 960dp x 720dp, per
+ // http://developer.android.com/guide/practices/screens_support.html#range
+ // For car, ignore the dp limitation. It's physically impossible to rotate the car's screen
+ // so if the orientation is forced, we need to respect that no matter what.
+ final boolean isCar = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_AUTOMOTIVE);
+ // For TV, it's usually 960dp x 540dp, ignore the size limitation.
+ // so if the orientation is forced, we need to respect that no matter what.
+ final boolean isTv = mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LEANBACK);
+ mForceDefaultOrientation = ((longSizeDp >= 960 && shortSizeDp >= 720) || isCar || isTv) &&
+ res.getBoolean(com.android.internal.R.bool.config_forceDefaultOrientation) &&
+ // For debug purposes the next line turns this feature off with:
+ // $ adb shell setprop config.override_forced_orient true
+ // $ adb shell wm size reset
+ !"true".equals(SystemProperties.get("config.override_forced_orient"));
+ }
+
+ void setRotation(int rotation) {
+ if (mOrientationListener != null) {
+ mOrientationListener.setCurrentRotation(rotation);
+ }
+ }
+
+ void setCurrentOrientation(int newOrientation) {
+ if (newOrientation != mCurrentAppOrientation) {
+ mCurrentAppOrientation = newOrientation;
+ if (isDefaultDisplay) {
+ updateOrientationListenerLw();
+ }
+ }
+ }
+
+ /** @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true. */
+ boolean isDefaultOrientationForced() {
+ return mForceDefaultOrientation;
+ }
+
+ public int getLandscapeRotation() {
+ return mLandscapeRotation;
+ }
+
+ public int getSeascapeRotation() {
+ return mSeascapeRotation;
+ }
+
+ public int getPortraitRotation() {
+ return mPortraitRotation;
+ }
+
+ public int getUpsideDownRotation() {
+ return mUpsideDownRotation;
+ }
+
+ public int getCurrentAppOrientation() {
+ return mCurrentAppOrientation;
+ }
+
+ public DisplayPolicy getDisplayPolicy() {
+ return mDisplayPolicy;
+ }
+
+ public WindowOrientationListener getOrientationListener() {
+ return mOrientationListener;
+ }
+
+ public int getUserRotation() {
+ return mUserRotation;
+ }
+
+ public int getUserRotationMode() {
+ return mUserRotationMode;
+ }
+
+ public void updateOrientationListener() {
+ synchronized (mLock) {
+ updateOrientationListenerLw();
+ }
+ }
+
+ /**
+ * Various use cases for invoking this function:
+ * <li>Screen turning off, should always disable listeners if already enabled.</li>
+ * <li>Screen turned on and current app has sensor based orientation, enable listeners
+ * if not already enabled.</li>
+ * <li>Screen turned on and current app does not have sensor orientation, disable listeners
+ * if already enabled.</li>
+ * <li>Screen turning on and current app has sensor based orientation, enable listeners
+ * if needed.</li>
+ * <li>screen turning on and current app has nosensor based orientation, do nothing.</li>
+ */
+ private void updateOrientationListenerLw() {
+ if (mOrientationListener == null || !mOrientationListener.canDetectOrientation()) {
+ // If sensor is turned off or nonexistent for some reason.
+ return;
+ }
+
+ final boolean screenOnEarly = mDisplayPolicy.isScreenOnEarly();
+ final boolean awake = mDisplayPolicy.isAwake();
+ final boolean keyguardDrawComplete = mDisplayPolicy.isKeyguardDrawComplete();
+ final boolean windowManagerDrawComplete = mDisplayPolicy.isWindowManagerDrawComplete();
+
+ // Could have been invoked due to screen turning on or off or
+ // change of the currently visible window's orientation.
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "screenOnEarly=" + screenOnEarly
+ + ", awake=" + awake + ", currentAppOrientation=" + mCurrentAppOrientation
+ + ", orientationSensorEnabled=" + mOrientationListener.mEnabled
+ + ", keyguardDrawComplete=" + keyguardDrawComplete
+ + ", windowManagerDrawComplete=" + windowManagerDrawComplete);
+
+ boolean disable = true;
+ // Note: We postpone the rotating of the screen until the keyguard as well as the
+ // window manager have reported a draw complete or the keyguard is going away in dismiss
+ // mode.
+ if (screenOnEarly && awake && ((keyguardDrawComplete && windowManagerDrawComplete))) {
+ if (needSensorRunning()) {
+ disable = false;
+ // Enable listener if not already enabled.
+ if (!mOrientationListener.mEnabled) {
+ // Don't clear the current sensor orientation if the keyguard is going away in
+ // dismiss mode. This allows window manager to use the last sensor reading to
+ // determine the orientation vs. falling back to the last known orientation if
+ // the sensor reading was cleared which can cause it to relaunch the app that
+ // will show in the wrong orientation first before correcting leading to app
+ // launch delays.
+ mOrientationListener.enable(true /* clearCurrentRotation */);
+ }
+ }
+ }
+ // Check if sensors need to be disabled.
+ if (disable && mOrientationListener.mEnabled) {
+ mOrientationListener.disable();
+ }
+ }
+
+ /**
+ * We always let the sensor be switched on by default except when
+ * the user has explicitly disabled sensor based rotation or when the
+ * screen is switched off.
+ */
+ private boolean needSensorRunning() {
+ if (mSupportAutoRotation) {
+ if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
+ || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
+ // If the application has explicitly requested to follow the
+ // orientation, then we need to turn the sensor on.
+ return true;
+ }
+ }
+
+ final int dockMode = mDisplayPolicy.getDockMode();
+ if ((mDisplayPolicy.isCarDockEnablesAccelerometer()
+ && dockMode == Intent.EXTRA_DOCK_STATE_CAR)
+ || (mDisplayPolicy.isDeskDockEnablesAccelerometer()
+ && (dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK))) {
+ // Enable accelerometer if we are docked in a dock that enables accelerometer
+ // orientation management.
+ return true;
+ }
+
+ if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
+ // If the setting for using the sensor by default is enabled, then
+ // we will always leave it on. Note that the user could go to
+ // a window that forces an orientation that does not use the
+ // sensor and in theory we could turn it off... however, when next
+ // turning it on we won't have a good value for the current
+ // orientation for a little bit, which can cause orientation
+ // changes to lag, so we'd like to keep it always on. (It will
+ // still be turned off when the screen is off.)
+
+ // When locked we can provide rotation suggestions users can approve to change the
+ // current screen rotation. To do this the sensor needs to be running.
+ return mSupportAutoRotation &&
+ mShowRotationSuggestions == Settings.Secure.SHOW_ROTATION_SUGGESTIONS_ENABLED;
+ }
+ return mSupportAutoRotation;
+ }
+
+ /**
+ * Given an orientation constant, returns the appropriate surface rotation,
+ * taking into account sensors, docking mode, rotation lock, and other factors.
+ *
+ * @param orientation An orientation constant, such as
+ * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+ * @param lastRotation The most recently used rotation.
+ * @param defaultDisplay Flag indicating whether the rotation is computed for the default
+ * display. Currently for all non-default displays sensors, docking mode,
+ * rotation lock and other factors are ignored.
+ * @return The surface rotation to use.
+ */
+ int rotationForOrientation(int orientation, int lastRotation) {
+ if (DEBUG_ORIENTATION) {
+ Slog.v(TAG, "rotationForOrientation(orient="
+ + orientation + ", last=" + lastRotation
+ + "); user=" + mUserRotation + " "
+ + (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
+ ? "USER_ROTATION_LOCKED" : "")
+ );
+ }
+
+ if (mForceDefaultOrientation) {
+ return Surface.ROTATION_0;
+ }
+
+ int sensorRotation = mOrientationListener != null
+ ? mOrientationListener.getProposedRotation() // may be -1
+ : -1;
+ if (sensorRotation < 0) {
+ sensorRotation = lastRotation;
+ }
+
+ final int lidState = mDisplayPolicy.getLidState();
+ final int dockMode = mDisplayPolicy.getDockMode();
+ final boolean hdmiPlugged = mDisplayPolicy.isHdmiPlugged();
+ final boolean carDockEnablesAccelerometer =
+ mDisplayPolicy.isCarDockEnablesAccelerometer();
+ final boolean deskDockEnablesAccelerometer =
+ mDisplayPolicy.isDeskDockEnablesAccelerometer();
+
+ final int preferredRotation;
+ if (!isDefaultDisplay) {
+ // For secondary displays we ignore things like displays sensors, docking mode and
+ // rotation lock, and always prefer a default rotation.
+ preferredRotation = Surface.ROTATION_0;
+ } else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
+ // Ignore sensor when lid switch is open and rotation is forced.
+ preferredRotation = mLidOpenRotation;
+ } else if (dockMode == Intent.EXTRA_DOCK_STATE_CAR
+ && (carDockEnablesAccelerometer || mCarDockRotation >= 0)) {
+ // Ignore sensor when in car dock unless explicitly enabled.
+ // This case can override the behavior of NOSENSOR, and can also
+ // enable 180 degree rotation while docked.
+ preferredRotation = carDockEnablesAccelerometer ? sensorRotation : mCarDockRotation;
+ } else if ((dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
+ && (deskDockEnablesAccelerometer || mDeskDockRotation >= 0)) {
+ // Ignore sensor when in desk dock unless explicitly enabled.
+ // This case can override the behavior of NOSENSOR, and can also
+ // enable 180 degree rotation while docked.
+ preferredRotation = deskDockEnablesAccelerometer ? sensorRotation : mDeskDockRotation;
+ } else if (hdmiPlugged && mDemoHdmiRotationLock) {
+ // Ignore sensor when plugged into HDMI when demo HDMI rotation lock enabled.
+ // Note that the dock orientation overrides the HDMI orientation.
+ preferredRotation = mDemoHdmiRotation;
+ } else if (hdmiPlugged && dockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
+ && mUndockedHdmiRotation >= 0) {
+ // Ignore sensor when plugged into HDMI and an undocked orientation has
+ // been specified in the configuration (only for legacy devices without
+ // full multi-display support).
+ // Note that the dock orientation overrides the HDMI orientation.
+ preferredRotation = mUndockedHdmiRotation;
+ } else if (mDemoRotationLock) {
+ // Ignore sensor when demo rotation lock is enabled.
+ // Note that the dock orientation and HDMI rotation lock override this.
+ preferredRotation = mDemoRotation;
+ } else if (mDisplayPolicy.isPersistentVrModeEnabled()) {
+ // While in VR, apps always prefer a portrait rotation. This does not change
+ // any apps that explicitly set landscape, but does cause sensors be ignored,
+ // and ignored any orientation lock that the user has set (this conditional
+ // should remain above the ORIENTATION_LOCKED conditional below).
+ preferredRotation = mPortraitRotation;
+ } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
+ // Application just wants to remain locked in the last rotation.
+ preferredRotation = lastRotation;
+ } else if (!mSupportAutoRotation) {
+ // If we don't support auto-rotation then bail out here and ignore
+ // the sensor and any rotation lock settings.
+ preferredRotation = -1;
+ } else if ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+ && (orientation == ActivityInfo.SCREEN_ORIENTATION_USER
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER))
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
+ // Otherwise, use sensor only if requested by the application or enabled
+ // by default for USER or UNSPECIFIED modes. Does not apply to NOSENSOR.
+ if (mAllowAllRotations < 0) {
+ // Can't read this during init() because the context doesn't
+ // have display metrics at that time so we cannot determine
+ // tablet vs. phone then.
+ mAllowAllRotations = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_allowAllRotations) ? 1 : 0;
+ }
+ if (sensorRotation != Surface.ROTATION_180
+ || mAllowAllRotations == 1
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+ || orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_USER) {
+ preferredRotation = sensorRotation;
+ } else {
+ preferredRotation = lastRotation;
+ }
+ } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED
+ && orientation != ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
+ // Apply rotation lock. Does not apply to NOSENSOR.
+ // The idea is that the user rotation expresses a weak preference for the direction
+ // of gravity and as NOSENSOR is never affected by gravity, then neither should
+ // NOSENSOR be affected by rotation lock (although it will be affected by docks).
+ preferredRotation = mUserRotation;
+ } else {
+ // No overriding preference.
+ // We will do exactly what the application asked us to do.
+ preferredRotation = -1;
+ }
+
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ // Return portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mPortraitRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ // Return landscape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mLandscapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ // Return reverse portrait unless overridden.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mUpsideDownRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ // Return seascape unless overridden.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ return mSeascapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ // Return either landscape rotation.
+ if (isLandscapeOrSeascape(preferredRotation)) {
+ return preferredRotation;
+ }
+ if (isLandscapeOrSeascape(lastRotation)) {
+ return lastRotation;
+ }
+ return mLandscapeRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // Return either portrait rotation.
+ if (isAnyPortrait(preferredRotation)) {
+ return preferredRotation;
+ }
+ if (isAnyPortrait(lastRotation)) {
+ return lastRotation;
+ }
+ return mPortraitRotation;
+
+ default:
+ // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,
+ // just return the preferred orientation we already calculated.
+ if (preferredRotation >= 0) {
+ return preferredRotation;
+ }
+ return Surface.ROTATION_0;
+ }
+ }
+
+ private boolean isLandscapeOrSeascape(int rotation) {
+ return rotation == mLandscapeRotation || rotation == mSeascapeRotation;
+ }
+
+ private boolean isAnyPortrait(int rotation) {
+ return rotation == mPortraitRotation || rotation == mUpsideDownRotation;
+ }
+
+ /**
+ * Given an orientation constant and a rotation, returns true if the rotation
+ * has compatible metrics to the requested orientation. For example, if
+ * the application requested landscape and got seascape, then the rotation
+ * has compatible metrics; if the application requested portrait and got landscape,
+ * then the rotation has incompatible metrics; if the application did not specify
+ * a preference, then anything goes.
+ *
+ * @param orientation An orientation constant, such as
+ * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
+ * @param rotation The rotation to check.
+ * @return True if the rotation is compatible with the requested orientation.
+ */
+ boolean rotationHasCompatibleMetrics(int orientation, int rotation) {
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+ return isAnyPortrait(rotation);
+
+ case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+ return isLandscapeOrSeascape(rotation);
+
+ default:
+ return true;
+ }
+ }
+
+ private boolean isValidRotationChoice(final int preferredRotation) {
+ // Determine if the given app orientation is compatible with the provided rotation choice.
+ switch (mCurrentAppOrientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
+ // Works with any of the 4 rotations.
+ return preferredRotation >= 0;
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // It's possible for the user pref to be set at 180 because of FULL_USER. This would
+ // make switching to USER_PORTRAIT appear at 180. Provide choice to back to portrait
+ // but never to go to 180.
+ return preferredRotation == mPortraitRotation;
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ // Works landscape or seascape.
+ return isLandscapeOrSeascape(preferredRotation);
+
+ case ActivityInfo.SCREEN_ORIENTATION_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+ // Works with any rotation except upside down.
+ return (preferredRotation >= 0) && (preferredRotation != mUpsideDownRotation);
+ }
+
+ return false;
+ }
+
+ private boolean isRotationChoicePossible(int orientation) {
+ // Rotation choice is only shown when the user is in locked mode.
+ if (mUserRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) return false;
+
+ // We should only enable rotation choice if the rotation isn't forced by the lid, dock,
+ // demo, hdmi, vr, etc mode.
+
+ // Determine if the rotation is currently forced.
+ if (mForceDefaultOrientation) {
+ return false; // Rotation is forced to default orientation.
+ }
+
+ final int lidState = mDisplayPolicy.getLidState();
+ if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
+ return false; // Rotation is forced mLidOpenRotation.
+ }
+
+ final int dockMode = mDisplayPolicy.getDockMode();
+ final boolean carDockEnablesAccelerometer = false;
+ if (dockMode == Intent.EXTRA_DOCK_STATE_CAR && !carDockEnablesAccelerometer) {
+ return false; // Rotation forced to mCarDockRotation.
+ }
+
+ final boolean deskDockEnablesAccelerometer =
+ mDisplayPolicy.isDeskDockEnablesAccelerometer();
+ if ((dockMode == Intent.EXTRA_DOCK_STATE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_LE_DESK
+ || dockMode == Intent.EXTRA_DOCK_STATE_HE_DESK)
+ && !deskDockEnablesAccelerometer) {
+ return false; // Rotation forced to mDeskDockRotation.
+ }
+
+ final boolean hdmiPlugged = mDisplayPolicy.isHdmiPlugged();
+ if (hdmiPlugged && mDemoHdmiRotationLock) {
+ return false; // Rotation forced to mDemoHdmiRotation.
+
+ } else if (hdmiPlugged && dockMode == Intent.EXTRA_DOCK_STATE_UNDOCKED
+ && mUndockedHdmiRotation >= 0) {
+ return false; // Rotation forced to mUndockedHdmiRotation.
+
+ } else if (mDemoRotationLock) {
+ return false; // Rotation forced to mDemoRotation.
+
+ } else if (mDisplayPolicy.isPersistentVrModeEnabled()) {
+ return false; // Rotation forced to mPortraitRotation.
+
+ } else if (!mSupportAutoRotation) {
+ return false;
+ }
+
+ // Ensure that some rotation choice is possible for the given orientation.
+ switch (orientation) {
+ case ActivityInfo.SCREEN_ORIENTATION_FULL_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_USER:
+ case ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:
+ case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:
+ // NOSENSOR description is ambiguous, in reality WM ignores user choice.
+ return true;
+ }
+
+ // Rotation is forced, should be controlled by system.
+ return false;
+ }
+
+ /** Notify the StatusBar that system rotation suggestion has changed. */
+ private void sendProposedRotationChangeToStatusBarInternal(int rotation, boolean isValid) {
+ if (mStatusBarManagerInternal == null) {
+ mStatusBarManagerInternal = LocalServices.getService(StatusBarManagerInternal.class);
+ }
+ if (mStatusBarManagerInternal != null) {
+ mStatusBarManagerInternal.onProposedRotationChanged(rotation, isValid);
+ }
+ }
+
+ private static String allowAllRotationsToString(int allowAll) {
+ switch (allowAll) {
+ case -1:
+ return "unknown";
+ case 0:
+ return "false";
+ case 1:
+ return "true";
+ default:
+ return Integer.toString(allowAll);
+ }
+ }
+
+ public void onUserSwitch() {
+ if (mSettingsObserver != null) {
+ mSettingsObserver.onChange(false);
+ }
+ }
+
+ /** Return whether the rotation settings has changed. */
+ private boolean updateSettings() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ boolean shouldUpdateRotation = false;
+
+ synchronized (mLock) {
+ boolean shouldUpdateOrientationListener = false;
+
+ // Configure rotation suggestions.
+ final int showRotationSuggestions = Settings.Secure.getIntForUser(resolver,
+ Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
+ Settings.Secure.SHOW_ROTATION_SUGGESTIONS_DEFAULT,
+ UserHandle.USER_CURRENT);
+ if (mShowRotationSuggestions != showRotationSuggestions) {
+ mShowRotationSuggestions = showRotationSuggestions;
+ shouldUpdateOrientationListener = true;
+ }
+
+ // Configure rotation lock.
+ final int userRotation = Settings.System.getIntForUser(resolver,
+ Settings.System.USER_ROTATION, Surface.ROTATION_0,
+ UserHandle.USER_CURRENT);
+ if (mUserRotation != userRotation) {
+ mUserRotation = userRotation;
+ shouldUpdateRotation = true;
+ }
+
+ final int userRotationMode = Settings.System.getIntForUser(resolver,
+ Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0
+ ? WindowManagerPolicy.USER_ROTATION_FREE
+ : WindowManagerPolicy.USER_ROTATION_LOCKED;
+ if (mUserRotationMode != userRotationMode) {
+ mUserRotationMode = userRotationMode;
+ shouldUpdateOrientationListener = true;
+ shouldUpdateRotation = true;
+ }
+
+ if (shouldUpdateOrientationListener) {
+ updateOrientationListenerLw(); // Enable or disable the orientation listener.
+ }
+ }
+
+ return shouldUpdateRotation;
+ }
+
+ void dump(String prefix, PrintWriter pw) {
+ pw.println(prefix + "DisplayRotation");
+ pw.println(prefix + " mCurrentAppOrientation="
+ + ActivityInfo.screenOrientationToString(mCurrentAppOrientation));
+ pw.print(prefix + " mLandscapeRotation=" + Surface.rotationToString(mLandscapeRotation));
+ pw.println(" mSeascapeRotation=" + Surface.rotationToString(mSeascapeRotation));
+ pw.print(prefix + " mPortraitRotation=" + Surface.rotationToString(mPortraitRotation));
+ pw.println(" mUpsideDownRotation=" + Surface.rotationToString(mUpsideDownRotation));
+
+ pw.print(prefix + " mSupportAutoRotation=" + mSupportAutoRotation);
+ if (mOrientationListener != null) {
+ pw.print(" mOrientationSensorEnabled=" + mOrientationListener.mEnabled);
+ }
+ pw.println();
+
+ pw.print(prefix + " mCarDockRotation=" + Surface.rotationToString(mCarDockRotation));
+ pw.println(" mDeskDockRotation=" + Surface.rotationToString(mDeskDockRotation));
+ pw.print(prefix + " mUserRotationMode="
+ + WindowManagerPolicy.userRotationModeToString(mUserRotationMode));
+ pw.print(" mUserRotation=" + Surface.rotationToString(mUserRotation));
+ pw.println(" mAllowAllRotations=" + allowAllRotationsToString(mAllowAllRotations));
+
+ pw.print(prefix + " mDemoHdmiRotation=" + Surface.rotationToString(mDemoHdmiRotation));
+ pw.print(" mDemoHdmiRotationLock=" + mDemoHdmiRotationLock);
+ pw.println(" mUndockedHdmiRotation=" + Surface.rotationToString(mUndockedHdmiRotation));
+ pw.println(prefix + " mLidOpenRotation=" + Surface.rotationToString(mLidOpenRotation));
+ }
+
+ private class OrientationListener extends WindowOrientationListener {
+ final SparseArray<Runnable> mRunnableCache = new SparseArray<>(5);
+ boolean mEnabled;
+
+ OrientationListener(Context context, Handler handler) {
+ super(context, handler);
+ }
+
+ private class UpdateRunnable implements Runnable {
+ final int mRotation;
+
+ UpdateRunnable(int rotation) {
+ mRotation = rotation;
+ }
+
+ @Override
+ public void run() {
+ // Send interaction hint to improve redraw performance.
+ mService.mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
+ if (isRotationChoicePossible(mCurrentAppOrientation)) {
+ final boolean isValid = isValidRotationChoice(mRotation);
+ sendProposedRotationChangeToStatusBarInternal(mRotation, isValid);
+ } else {
+ mService.updateRotation(false /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ }
+ }
+ }
+
+ @Override
+ public void onProposedRotationChanged(int rotation) {
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "onProposedRotationChanged, rotation=" + rotation);
+ Runnable r = mRunnableCache.get(rotation, null);
+ if (r == null) {
+ r = new UpdateRunnable(rotation);
+ mRunnableCache.put(rotation, r);
+ }
+ getHandler().post(r);
+ }
+
+ @Override
+ public void enable(boolean clearCurrentRotation) {
+ super.enable(clearCurrentRotation);
+ mEnabled = true;
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Enabling listeners");
+ }
+
+ @Override
+ public void disable() {
+ super.disable();
+ mEnabled = false;
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "Disabling listeners");
+ }
+ }
+
+ private class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ void observe() {
+ final ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.SHOW_ROTATION_SUGGESTIONS), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.ACCELEROMETER_ROTATION), false, this,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.USER_ROTATION), false, this,
+ UserHandle.USER_ALL);
+ updateSettings();
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ if (updateSettings()) {
+ mService.updateRotation(true /* alwaysSendConfiguration */,
+ false /* forceRelayout */);
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index a1639c2..74a8a35 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -76,7 +76,8 @@
/**
* Positions the task stack at the given position in the task stack container.
*/
- public void positionChildAt(StackWindowController child, int position) {
+ public void positionChildAt(StackWindowController child, int position,
+ boolean includingParents) {
synchronized (mWindowMap) {
if (DEBUG_STACK) Slog.i(TAG_WM, "positionTaskStackAt: positioning stack=" + child
+ " at " + position);
@@ -90,7 +91,7 @@
"positionTaskStackAt: could not find stack=" + this);
return;
}
- mContainer.positionStackAt(position, child.mContainer);
+ mContainer.positionStackAt(position, child.mContainer, includingParents);
}
}
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 016921d..b5e2f01 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -123,17 +123,14 @@
return appWindowToken.mInputDispatchingTimeoutNanos;
}
} else if (windowState != null) {
- try {
- // Notify the activity manager about the timeout and let it decide whether
- // to abort dispatching or keep waiting.
- long timeout = ActivityManager.getService().inputDispatchingTimedOut(
- windowState.mSession.mPid, aboveSystem, reason);
- if (timeout >= 0) {
- // The activity manager declined to abort dispatching.
- // Wait a bit longer and timeout again later.
- return timeout * 1000000L; // nanoseconds
- }
- } catch (RemoteException ex) {
+ // Notify the activity manager about the timeout and let it decide whether
+ // to abort dispatching or keep waiting.
+ long timeout = mService.mAtmInternal.inputDispatchingTimedOut(
+ windowState.mSession.mPid, aboveSystem, reason);
+ if (timeout >= 0) {
+ // The activity manager declined to abort dispatching.
+ // Wait a bit longer and timeout again later.
+ return timeout * 1000000L; // nanoseconds
}
}
return 0; // abort dispatching
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index d53a21b..c4beb55 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -399,7 +399,8 @@
this.inDrag = inDrag;
wallpaperController = mService.mRoot.mWallpaperController;
- mService.mRoot.getDisplayContent(mDisplayId).forAllWindows(this,
+ // TODO(b/112081256): Use independent InputMonitor for each display.
+ mService.mRoot/*.getDisplayContent(mDisplayId)*/.forAllWindows(this,
true /* traverseTopToBottom */);
if (mAddWallpaperInputConsumerHandle) {
// No visible wallpaper found, add the wallpaper input consumer at the end.
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 3df4eb7..ca4fa64 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -134,6 +134,9 @@
// transaction from the global transaction.
private final SurfaceControl.Transaction mDisplayTransaction = new SurfaceControl.Transaction();
+ private final Consumer<DisplayContent> mDisplayContentConfigChangesConsumer =
+ mService.mPolicy::onConfigurationChanged;
+
private final Consumer<WindowState> mCloseSystemDialogsConsumer = w -> {
if (w.mHasSurface) {
try {
@@ -379,7 +382,7 @@
prepareFreezingTaskBounds();
super.onConfigurationChanged(newParentConfig);
- mService.mPolicy.onConfigurationChanged();
+ forAllDisplays(mDisplayContentConfigChangesConsumer);
}
/**
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 9075b6c..2b84937 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -751,7 +751,7 @@
// be inserted into is calculated properly in
// {@link DisplayContent#findPositionForStack()} in both cases, we can just request that
// the stack is put at top here.
- mDisplayContent.positionStackAt(POSITION_TOP, this);
+ mDisplayContent.positionStackAt(POSITION_TOP, this, false /* includingParents */);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimationSpec.java b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
index 548e23a..825255e 100644
--- a/services/core/java/com/android/server/wm/WindowAnimationSpec.java
+++ b/services/core/java/com/android/server/wm/WindowAnimationSpec.java
@@ -99,13 +99,7 @@
tmp.transformation.getMatrix().postTranslate(mPosition.x, mPosition.y);
t.setMatrix(leash, tmp.transformation.getMatrix(), tmp.floats);
t.setAlpha(leash, tmp.transformation.getAlpha());
- if (mStackClipMode == STACK_CLIP_NONE) {
- t.setWindowCrop(leash, tmp.transformation.getClipRect());
- } else if (mStackClipMode == STACK_CLIP_AFTER_ANIM) {
- mTmpRect.set(mStackBounds);
- // Offset stack bounds to stack position so the final crop is in screen space.
- mTmpRect.offsetTo(mPosition.x, mPosition.y);
- t.setFinalCrop(leash, mTmpRect);
+ if (mStackClipMode == STACK_CLIP_NONE || mStackClipMode == STACK_CLIP_AFTER_ANIM) {
t.setWindowCrop(leash, tmp.transformation.getClipRect());
} else {
mTmpRect.set(mStackBounds);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 9b792e3..ea68e17 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -2480,10 +2480,7 @@
dc.setLastOrientation(req);
//send a message to Policy indicating orientation change to take
//action like disabling/enabling sensors etc.,
- // TODO(multi-display): Implement policy for secondary displays.
- if (dc.isDefaultDisplay) {
- mPolicy.setCurrentOrientationLw(req);
- }
+ dc.getDisplayRotation().setCurrentOrientation(req);
return dc.updateRotationUnchecked(forceUpdate);
}
return false;
@@ -2492,27 +2489,6 @@
}
}
- // If this is true we have updated our desired orientation, but not yet
- // changed the real orientation our applied our screen rotation animation.
- // For example, because a previous screen rotation was in progress.
- boolean rotationNeedsUpdateLocked() {
- // TODO(multi-display): Check for updates on all displays. Need to have per-display policy
- // to implement WindowManagerPolicy#rotationForOrientationLw() correctly.
- final DisplayContent defaultDisplayContent = getDefaultDisplayContentLocked();
- final int lastOrientation = defaultDisplayContent.getLastOrientation();
- final int oldRotation = defaultDisplayContent.getRotation();
- final boolean oldAltOrientation = defaultDisplayContent.getAltOrientation();
-
- final int rotation = mPolicy.rotationForOrientationLw(lastOrientation, oldRotation,
- true /* defaultDisplay */);
- boolean altOrientation = !mPolicy.rotationHasCompatibleMetricsLw(
- lastOrientation, rotation);
- if (oldRotation == rotation && oldAltOrientation == altOrientation) {
- return false;
- }
- return true;
- }
-
@Override
public int[] setNewDisplayOverrideConfiguration(Configuration overrideConfig, int displayId) {
if (!checkCallingPermission(MANAGE_APP_TOKENS, "setNewDisplayOverrideConfiguration()")) {
@@ -3841,28 +3817,31 @@
long origId = Binder.clearCallingIdentity();
try {
- // TODO(multi-display): Update rotation for different displays separately.
- final boolean rotationChanged;
- final int displayId;
synchronized (mWindowMap) {
- final DisplayContent displayContent = getDefaultDisplayContentLocked();
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
- rotationChanged = displayContent.updateRotationUnchecked();
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- if (!rotationChanged || forceRelayout) {
- displayContent.setLayoutNeeded();
+ boolean layoutNeeded = false;
+ final int displayCount = mRoot.mChildren.size();
+ for (int i = 0; i < displayCount; ++i) {
+ final DisplayContent displayContent = mRoot.mChildren.get(i);
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: display");
+ final boolean rotationChanged = displayContent.updateRotationUnchecked();
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+
+ if (!rotationChanged || forceRelayout) {
+ displayContent.setLayoutNeeded();
+ layoutNeeded = true;
+ }
+ if (rotationChanged || alwaysSendConfiguration) {
+ mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
+ .sendToTarget();
+ }
+ }
+
+ if (layoutNeeded) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"updateRotation: performSurfacePlacement");
mWindowPlacerLocked.performSurfacePlacement();
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
- displayId = displayContent.getDisplayId();
- }
-
- if (rotationChanged || alwaysSendConfiguration) {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "updateRotation: sendNewConfiguration");
- sendNewConfiguration(displayId);
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -3871,6 +3850,13 @@
}
@Override
+ public WindowManagerPolicy.DisplayContentInfo getDefaultDisplayContentInfo() {
+ synchronized (mWindowMap) {
+ return getDefaultDisplayContentLocked();
+ }
+ }
+
+ @Override
public int getDefaultDisplayRotation() {
synchronized (mWindowMap) {
return getDefaultDisplayContentLocked().getRotation();
@@ -5792,7 +5778,7 @@
displayContent.updateDisplayInfo();
screenRotationAnimation = new ScreenRotationAnimation(mContext, displayContent,
- mPolicy.isDefaultOrientationForced(), isSecure,
+ displayContent.getDisplayRotation().isDefaultOrientationForced(), isSecure,
this);
mAnimator.setScreenRotationAnimationLocked(mFrozenDisplayId,
screenRotationAnimation);
@@ -6082,23 +6068,26 @@
@Override
public void createInputConsumer(IBinder token, String name, InputChannel inputChannel) {
synchronized (mWindowMap) {
- mRoot.forAllDisplays(dc -> {
- dc.getInputMonitor().createInputConsumer(token, name, inputChannel,
+ // TODO(b/112049699): Fix this for multiple displays. There is only one inputChannel
+ // here to accept the return value.
+ DisplayContent display = mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
+ if (display != null) {
+ display.getInputMonitor().createInputConsumer(token, name, inputChannel,
Binder.getCallingPid(), Binder.getCallingUserHandle());
- });
+ }
}
}
@Override
public boolean destroyInputConsumer(String name) {
synchronized (mWindowMap) {
- AtomicBoolean retValue = new AtomicBoolean(true);
- mRoot.forAllDisplays(dc -> {
- if (!dc.getInputMonitor().destroyInputConsumer(name)) {
- retValue.set(false);
- }
- });
- return retValue.get();
+ // TODO(b/112049699): Fix this for multiple displays. For consistency with
+ // createInputConsumer above.
+ DisplayContent display = mRoot.getDisplayContent(Display.DEFAULT_DISPLAY);
+ if (display != null) {
+ return display.getInputMonitor().destroyInputConsumer(name);
+ }
+ return false;
}
}
@@ -6761,8 +6750,10 @@
public void onOverlayChanged() {
synchronized (mWindowMap) {
- mPolicy.onOverlayChangedLw();
- getDefaultDisplayContentLocked().updateDisplayInfo();
+ mRoot.forAllDisplays(displayContent -> {
+ mPolicy.onOverlayChangedLw(displayContent);
+ displayContent.updateDisplayInfo();
+ });
requestTraversal();
}
}
@@ -7090,19 +7081,24 @@
@Override
public void dontOverrideDisplayInfo(int displayId) {
- synchronized (mWindowMap) {
- final DisplayContent dc = getDisplayContentOrCreate(displayId);
- if (dc == null) {
- throw new IllegalArgumentException(
- "Trying to register a non existent display.");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mWindowMap) {
+ final DisplayContent dc = getDisplayContentOrCreate(displayId);
+ if (dc == null) {
+ throw new IllegalArgumentException(
+ "Trying to register a non existent display.");
+ }
+ // We usually set the override info in DisplayManager so that we get consistent
+ // values when displays are changing. However, we don't do this for displays that
+ // serve as containers for ActivityViews because we don't want letter-/pillar-boxing
+ // during resize.
+ dc.mShouldOverrideDisplayConfiguration = false;
+ mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId,
+ null /* info */);
}
- // We usually set the override info in DisplayManager so that we get consistent
- // values when displays are changing. However, we don't do this for displays that
- // serve as containers for ActivityViews because we don't want letter-/pillar-boxing
- // during resize.
- dc.mShouldOverrideDisplayConfiguration = false;
- mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(displayId,
- null /* info */);
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
@@ -7141,11 +7137,7 @@
}
finishSeamlessRotation();
- final DisplayContent displayContent = w.getDisplayContent();
- if (displayContent.updateRotationUnchecked()) {
- mH.obtainMessage(H.SEND_NEW_CONFIGURATION, displayContent.getDisplayId())
- .sendToTarget();
- }
+ w.getDisplayContent().updateRotationAndSendNewConfigIfNeeded();
}
}
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index aced8e4..08decdf 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -569,7 +569,7 @@
// animation after the old one finally finishes. It's better to defer the
// app transition.
if (screenRotationAnimation != null && screenRotationAnimation.isAnimating() &&
- mService.rotationNeedsUpdateLocked()) {
+ mService.getDefaultDisplayContentLocked().rotationNeedsUpdate()) {
if (DEBUG_APP_TRANSITIONS) {
Slog.v(TAG, "Delaying app transition for screen rotation animation to finish");
}
diff --git a/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java b/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java
new file mode 100644
index 0000000..dd0a58d
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/KeyValueBackupJobTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+import android.os.Handler;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class KeyValueBackupJobTest {
+ private Context mContext;
+ private BackupManagerConstants mConstants;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = RuntimeEnvironment.application;
+ mConstants = new BackupManagerConstants(Handler.getMain(), mContext.getContentResolver());
+ mConstants.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mConstants.stop();
+ KeyValueBackupJob.cancel(mContext);
+ }
+
+ @Test
+ public void testIsScheduled_beforeScheduling_returnsFalse() {
+ boolean isScheduled = KeyValueBackupJob.isScheduled();
+
+ assertThat(isScheduled).isFalse();
+ }
+
+ @Test
+ public void testIsScheduled_afterScheduling_returnsTrue() {
+ KeyValueBackupJob.schedule(mContext, mConstants);
+
+ boolean isScheduled = KeyValueBackupJob.isScheduled();
+
+ assertThat(isScheduled).isTrue();
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index 8fab197..1f6ac8d 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -54,6 +54,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
+import static org.robolectric.shadow.api.Shadow.extract;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.util.Collections.emptyList;
@@ -79,6 +80,7 @@
import android.net.Uri;
import android.os.DeadObjectException;
import android.os.Handler;
+import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
@@ -101,6 +103,7 @@
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderClasses;
import com.android.server.testing.SystemLoaderPackages;
+import com.android.server.testing.shadows.FrameworkShadowLooper;
import com.android.server.testing.shadows.ShadowBackupDataInput;
import com.android.server.testing.shadows.ShadowBackupDataOutput;
import com.android.server.testing.shadows.ShadowEventLog;
@@ -143,10 +146,11 @@
manifest = Config.NONE,
sdk = 26,
shadows = {
+ FrameworkShadowLooper.class,
ShadowBackupDataInput.class,
ShadowBackupDataOutput.class,
ShadowEventLog.class,
- ShadowQueuedWork.class
+ ShadowQueuedWork.class,
})
@SystemLoaderPackages({"com.android.server.backup", "android.app.backup"})
@SystemLoaderClasses({IBackupTransport.class, IBackupAgent.class, PackageInfo.class})
@@ -171,6 +175,7 @@
private File mDataDir;
private Application mApplication;
private ShadowApplication mShadowApplication;
+ private FrameworkShadowLooper mShadowMainLooper;
private Context mContext;
@Before
@@ -183,6 +188,8 @@
mShadowApplication = shadowOf(mApplication);
mContext = mApplication;
+ mShadowMainLooper = extract(Looper.getMainLooper());
+
File cacheDir = mApplication.getCacheDir();
// Corresponds to /data/backup
mBaseStateDir = new File(cacheDir, "base_state");
@@ -337,7 +344,7 @@
runTask(task);
- assertEventLogged(EventLogTags.BACKUP_START, mTransport.transportDirName);
+ assertEventLogged(EventLogTags.BACKUP_START, mTransport.transportName);
}
@Test
@@ -1571,11 +1578,10 @@
}
private void runTask(PerformBackupTask task) {
- Message message = mBackupHandler.obtainMessage(BackupHandler.MSG_BACKUP_RESTORE_STEP, task);
- mBackupHandler.sendMessage(message);
- while (mShadowBackupLooper.getScheduler().areAnyRunnable()) {
- mShadowBackupLooper.runToEndOfTasks();
- }
+ // Pretend we are not on the main-thread to prevent RemoteCall from complaining
+ mShadowMainLooper.setCurrentThread(false);
+ task.run();
+ mShadowMainLooper.reset();
assertTaskPostConditions();
}
@@ -1699,7 +1705,7 @@
String transportDirName,
boolean nonIncremental,
PackageData... packages) {
- ArrayList<BackupRequest> backupRequests =
+ ArrayList<BackupRequest> keyValueBackupRequests =
Stream.of(packages)
.map(packageData -> packageData.packageName)
.map(BackupRequest::new)
@@ -1713,7 +1719,7 @@
mBackupManagerService,
transportClient,
transportDirName,
- backupRequests,
+ keyValueBackupRequests,
mOldJournal,
mObserver,
mMonitor,
diff --git a/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java b/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java
new file mode 100644
index 0000000..aec207d
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/FutureBackupCallbackTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import java.util.concurrent.CompletableFuture;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class FutureBackupCallbackTest {
+ @Test
+ public void testOperationComplete_completesFuture() throws Exception {
+ CompletableFuture<RemoteResult> future = new CompletableFuture<>();
+ FutureBackupCallback callback = new FutureBackupCallback(future);
+
+ callback.operationComplete(7);
+
+ assertThat(future.get()).isEqualTo(RemoteResult.successful(7));
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java b/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java
new file mode 100644
index 0000000..55db616
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/RemoteCallTest.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import static com.android.server.backup.testing.TestUtils.runToEndOfTasks;
+import static com.android.server.backup.testing.TestUtils.uncheck;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IBackupCallback;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.backup.testing.TestUtils.ThrowingRunnable;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.annotation.Config;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class RemoteCallTest {
+ /** A {@link RemoteCallable} that calls the callback immediately. */
+ private final RemoteCallable<IBackupCallback> IMMEDIATE_CALLABLE =
+ callback -> callback.operationComplete(0);
+
+ @Mock private RemoteCallable<IBackupCallback> mCallable;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ @Test
+ public void testCall_whenCancelledAndImmediateCallableAndTimeOut0_returnsCancel()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(true, IMMEDIATE_CALLABLE, 0);
+
+ RemoteResult result = runInWorkerThread(remoteCall::call);
+
+ assertThat(result).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ @Test
+ public void testCall_whenCancelledAndImmediateCallableAndTimeOut0_doesNotCallCallable()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(true, IMMEDIATE_CALLABLE, 0);
+
+ runInWorkerThread(remoteCall::call);
+
+ verify(mCallable, never()).call(any());
+ }
+
+ @Test
+ public void testCall_whenImmediateCallableAndTimeOut0AndCancelIsCalledBeforeCall_returnsCancel()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(IMMEDIATE_CALLABLE, 0);
+ remoteCall.cancel();
+
+ RemoteResult result = runInWorkerThread(remoteCall::call);
+
+ assertThat(result).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ @Test
+ public void
+ testCall_whenImmediateCallableAndTimeOut0AndCancelIsCalledBeforeCall_doesNotCallCallable()
+ throws Exception {
+ RemoteCall remoteCall = new RemoteCall(IMMEDIATE_CALLABLE, 0);
+ remoteCall.cancel();
+
+ runInWorkerThread(remoteCall::call);
+
+ verify(mCallable, never()).call(any());
+ }
+
+ @Test
+ public void testCall_whenImmediateCallableAndTimeOut0_returnsTimeOut() throws Exception {
+ RemoteCall remoteCall = new RemoteCall(IMMEDIATE_CALLABLE, 0);
+
+ RemoteResult result = runInWorkerThread(remoteCall::call);
+
+ assertThat(result).isEqualTo(RemoteResult.FAILED_TIMED_OUT);
+ }
+
+ @Test
+ public void testCall_whenTimeOut0_doesNotCallCallable() throws Exception {
+ RemoteCall remoteCall = new RemoteCall(mCallable, 0);
+
+ runInWorkerThread(remoteCall::call);
+
+ verify(mCallable, never()).call(any());
+ }
+
+ @Test
+ public void testCall_whenTimesOutBeforeCallbackIsCalled_returnsTimeOut() throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall =
+ new RemoteCall(
+ callback -> {
+ postDelayed(
+ Handler.getMain(), () -> callback.operationComplete(0), 1000);
+ scheduled.open();
+ },
+ 500);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ // Method runToEndOfTasks() will execute what was posted to the main handler, which is the
+ // completion of the callback and the time-out (that was scheduled by RemoteCall). But to be
+ // able to execute everything we have to ensure that runToEndOfTasks() is called *after*
+ // everything has been scheduled, that's why we use the condition variable scheduled, that
+ // is set to true (i.e. opened) when everything is scheduled, allowing us to run the tasks.
+ scheduled.block();
+ runToEndOfTasks(Looper.getMainLooper());
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_TIMED_OUT);
+ }
+
+ @Test
+ public void testCall_whenTimesOutBeforeCancelIsCalled_returnsTimeOut() throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall = new RemoteCall(callback -> scheduled.open(), 500);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ scheduled.block();
+ runToEndOfTasks(Looper.getMainLooper());
+ remoteCall.cancel();
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_TIMED_OUT);
+ }
+
+ @Test
+ public void testCall_whenCallbackIsCalledBeforeTimeOut_returnsSuccess() throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall =
+ new RemoteCall(
+ callback -> {
+ postDelayed(
+ Handler.getMain(), () -> callback.operationComplete(3), 500);
+ scheduled.open();
+ },
+ 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ scheduled.block();
+ runToEndOfTasks(Looper.getMainLooper());
+ assertThat(result.get()).isEqualTo(RemoteResult.successful(3));
+ }
+
+ @Test
+ public void testCall_whenCallbackIsCalledBeforeCancel_returnsSuccess() throws Exception {
+ CompletableFuture<IBackupCallback> callbackFuture = new CompletableFuture<>();
+ RemoteCall remoteCall = new RemoteCall(callbackFuture::complete, 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ // callbackFuture.get() will return when callable is executed (i.e. inside
+ // remoteCall.call()), at which point we can complete it.
+ IBackupCallback callback = callbackFuture.get();
+ callback.operationComplete(3);
+ remoteCall.cancel();
+ assertThat(result.get()).isEqualTo(RemoteResult.successful(3));
+ }
+
+ @Test
+ public void testCall_whenCancelIsCalledBeforeCallbackButAfterCall_returnsCancel()
+ throws Exception {
+ CompletableFuture<IBackupCallback> callbackFuture = new CompletableFuture<>();
+ RemoteCall remoteCall = new RemoteCall(callbackFuture::complete, 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ IBackupCallback callback = callbackFuture.get();
+ remoteCall.cancel();
+ callback.operationComplete(3);
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ @Test
+ public void testCall_whenCancelIsCalledBeforeTimeOutButAfterCall_returnsCancel()
+ throws Exception {
+ ConditionVariable scheduled = new ConditionVariable(false);
+ RemoteCall remoteCall = new RemoteCall(callback -> scheduled.open(), 1000);
+
+ Future<RemoteResult> result = runInWorkerThreadAsync(remoteCall::call);
+
+ scheduled.block();
+ remoteCall.cancel();
+ runToEndOfTasks(Looper.getMainLooper());
+ assertThat(result.get()).isEqualTo(RemoteResult.FAILED_CANCELLED);
+ }
+
+ private static <T> Future<T> runInWorkerThreadAsync(Callable<T> supplier) {
+ CompletableFuture<T> future = new CompletableFuture<>();
+ new Thread(() -> future.complete(uncheck(supplier)), "test-worker-thread").start();
+ return future;
+ }
+
+ private static <T> T runInWorkerThread(Callable<T> supplier) throws Exception {
+ return runInWorkerThreadAsync(supplier).get();
+ }
+
+ /** Unchecked version of {@link Handler#postDelayed(Runnable, long)}. */
+ private static void postDelayed(Handler handler, ThrowingRunnable runnable, long delayMillis) {
+ handler.postDelayed(() -> uncheck(runnable), delayMillis);
+ }
+
+ /** Unchecked version of {@link Handler#post(Runnable)}. */
+ private static void post(Handler handler, ThrowingRunnable runnable) {
+ handler.post(() -> uncheck(runnable));
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java b/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java
new file mode 100644
index 0000000..f1c4f27
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/RemoteResultTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.expectThrows;
+
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class RemoteResultTest {
+ @Test
+ public void testSucceeded_whenSuccessfulResult_returnsTrue() {
+ RemoteResult result = RemoteResult.successful(3);
+
+ boolean succeeded = result.succeeded();
+
+ assertThat(succeeded).isTrue();
+ }
+
+ @Test
+ public void testSucceeded_whenFailedResults_returnsFalse() {
+ boolean timeOutSucceeded = RemoteResult.FAILED_TIMED_OUT.succeeded();
+ boolean cancelledSucceeded = RemoteResult.FAILED_CANCELLED.succeeded();
+ boolean threadInterruptedSucceeded = RemoteResult.FAILED_THREAD_INTERRUPTED.succeeded();
+
+ assertThat(timeOutSucceeded).isFalse();
+ assertThat(cancelledSucceeded).isFalse();
+ assertThat(threadInterruptedSucceeded).isFalse();
+ }
+
+ @Test
+ public void testGet_whenSuccessfulResult_returnsValue() {
+ RemoteResult result = RemoteResult.successful(7);
+
+ long value = result.get();
+
+ assertThat(value).isEqualTo(7);
+ }
+
+ @Test
+ public void testGet_whenFailedResult_throws() {
+ RemoteResult result = RemoteResult.FAILED_TIMED_OUT;
+
+ expectThrows(IllegalStateException.class, result::get);
+ }
+
+ @Test
+ public void testToString() {
+ assertThat(RemoteResult.successful(3).toString()).isEqualTo("RemoteResult{3}");
+ assertThat(RemoteResult.FAILED_TIMED_OUT.toString())
+ .isEqualTo("RemoteResult{FAILED_TIMED_OUT}");
+ assertThat(RemoteResult.FAILED_CANCELLED.toString())
+ .isEqualTo("RemoteResult{FAILED_CANCELLED}");
+ assertThat(RemoteResult.FAILED_THREAD_INTERRUPTED.toString())
+ .isEqualTo("RemoteResult{FAILED_THREAD_INTERRUPTED}");
+ }
+
+ @Test
+ public void testEquals() {
+ assertThat(RemoteResult.successful(3).equals(RemoteResult.successful(3))).isTrue();
+ assertThat(RemoteResult.successful(3).equals(RemoteResult.successful(7))).isFalse();
+ assertThat(RemoteResult.successful(-1).equals(RemoteResult.successful(1))).isFalse();
+ assertThat(RemoteResult.successful(Long.MAX_VALUE).equals(RemoteResult.successful(-1)))
+ .isFalse();
+ assertThat(RemoteResult.successful(3).equals(RemoteResult.FAILED_TIMED_OUT)).isFalse();
+ assertThat(RemoteResult.successful(3).equals("3")).isFalse();
+ assertThat(RemoteResult.successful(3).equals(null)).isFalse();
+ assertThat(RemoteResult.FAILED_TIMED_OUT.equals(RemoteResult.FAILED_TIMED_OUT)).isTrue();
+ assertThat(RemoteResult.FAILED_TIMED_OUT.equals(RemoteResult.FAILED_CANCELLED)).isFalse();
+ }
+
+ /** @see Object#hashCode() */
+ @Test
+ public void testHashCode() {
+ RemoteResult result3 = RemoteResult.successful(3);
+ assertThat(result3.hashCode()).isEqualTo(result3.hashCode());
+ assertThat(result3.hashCode()).isEqualTo(RemoteResult.successful(3).hashCode());
+ assertThat(RemoteResult.FAILED_TIMED_OUT.hashCode())
+ .isEqualTo(RemoteResult.FAILED_TIMED_OUT.hashCode());
+ assertThat(RemoteResult.FAILED_CANCELLED.hashCode())
+ .isEqualTo(RemoteResult.FAILED_CANCELLED.hashCode());
+ assertThat(RemoteResult.FAILED_THREAD_INTERRUPTED.hashCode())
+ .isEqualTo(RemoteResult.FAILED_THREAD_INTERRUPTED.hashCode());
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java b/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java
new file mode 100644
index 0000000..e0d3c0c
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/remote/ServiceBackupCallbackTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.remote;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.backup.IBackupManager;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class ServiceBackupCallbackTest {
+ @Test
+ public void testOperationComplete_callsBackupManagerOpComplete() throws Exception {
+ IBackupManager backupManager = mock(IBackupManager.class);
+ ServiceBackupCallback callback = new ServiceBackupCallback(backupManager, 0x68e);
+
+ callback.operationComplete(7);
+
+ verify(backupManager).opComplete(0x68e, 7);
+ }
+}
diff --git a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
index 23d4ba4..084f27f 100644
--- a/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/BackupManagerServiceTestUtils.java
@@ -16,6 +16,8 @@
package com.android.server.backup.testing;
+import static com.android.server.backup.testing.TestUtils.runToEndOfTasks;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -46,8 +48,6 @@
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.shadows.ShadowBinder;
import org.robolectric.shadows.ShadowLog;
-import org.robolectric.shadows.ShadowLooper;
-import org.robolectric.shadows.ShadowSystemClock;
import java.io.File;
import java.lang.Thread.UncaughtExceptionHandler;
@@ -79,14 +79,7 @@
baseStateDir,
dataDir,
transportManager);
- ShadowLooper shadowBackupLooper = shadowOf(backupThread.getLooper());
- shadowBackupLooper.runToEndOfTasks();
- // Handler instances have their own clock, so advancing looper (with runToEndOfTasks())
- // above does NOT advance the handlers' clock, hence whenever a handler post messages with
- // specific time to the looper the time of those messages will be before the looper's time.
- // To fix this we advance SystemClock as well since that is from where the handlers read
- // time.
- ShadowSystemClock.setCurrentTimeMillis(shadowBackupLooper.getScheduler().getCurrentTime());
+ runToEndOfTasks(backupThread.getLooper());
return backupManagerService;
}
diff --git a/services/robotests/src/com/android/server/backup/testing/TestUtils.java b/services/robotests/src/com/android/server/backup/testing/TestUtils.java
index b657dd0..134cfd8 100644
--- a/services/robotests/src/com/android/server/backup/testing/TestUtils.java
+++ b/services/robotests/src/com/android/server/backup/testing/TestUtils.java
@@ -18,15 +18,33 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.robolectric.Shadows.shadowOf;
+
+import android.os.Looper;
+
import com.android.server.testing.shadows.ShadowEventLog;
import org.robolectric.shadows.ShadowLog;
+import org.robolectric.shadows.ShadowLooper;
+import org.robolectric.shadows.ShadowSystemClock;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.function.Predicate;
public class TestUtils {
+ /** Version of {@link ShadowLooper#runToEndOfTasks()} that also advances the system clock. */
+ public static void runToEndOfTasks(Looper looper) {
+ ShadowLooper shadowLooper = shadowOf(looper);
+ shadowLooper.runToEndOfTasks();
+ // Handler instances have their own clock, so advancing looper (with runToEndOfTasks())
+ // above does NOT advance the handlers' clock, hence whenever a handler post messages with
+ // specific time to the looper the time of those messages will be before the looper's time.
+ // To fix this we advance SystemClock as well since that is from where the handlers read
+ // time.
+ ShadowSystemClock.setCurrentTimeMillis(shadowLooper.getScheduler().getCurrentTime());
+ }
+
/** Reset logcat with {@link ShadowLog#reset()} before the test case. */
public static void assertLogcatAtMost(String tag, int level) {
assertThat(ShadowLog.getLogsForTag(tag).stream().allMatch(logItem -> logItem.type <= level))
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index d51c99b..5669819 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -551,7 +551,7 @@
// Home stack and activity are created in ActivityTestsBase#setupActivityManagerService
stack = mDefaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
if (onTop) {
- mDefaultDisplay.positionChildAtTop(stack);
+ mDefaultDisplay.positionChildAtTop(stack, false /* includingParents */);
} else {
mDefaultDisplay.positionChildAtBottom(stack);
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
index 420987d..41c7f1d 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
@@ -123,7 +123,7 @@
mDevicePolicyManager);
when(mDevicePolicyManager.createShowAdminSupportIntent(TEST_USER_ID, true))
.thenReturn(ADMIN_SUPPORT_INTENT);
- when(mAm.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
+ when(mService.getPackageManagerInternalLocked()).thenReturn(mPackageManagerInternal);
// Mock UserManager
when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
@@ -136,7 +136,7 @@
thenReturn(CONFIRM_CREDENTIALS_INTENT);
// Mock PackageManager
- when(mAm.getPackageManager()).thenReturn(mPackageManager);
+ when(mService.getPackageManager()).thenReturn(mPackageManager);
when(mPackageManager.getHarmfulAppWarning(TEST_PACKAGE_NAME, TEST_USER_ID))
.thenReturn(null);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 7e8697d..a9e0aa8 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -32,12 +32,16 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
+import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
+import android.content.pm.PackageManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.DisplayWindowController;
import org.junit.Rule;
@@ -128,17 +132,16 @@
}
ActivityManagerService setupActivityManagerService(TestActivityTaskManagerService atm) {
- final ActivityManagerService am = spy(new TestActivityManagerService(mContext, atm));
+ final TestActivityManagerService am = spy(new TestActivityManagerService(mContext, atm));
setupActivityManagerService(am, atm);
return am;
}
- void setupActivityManagerService(ActivityManagerService am, ActivityTaskManagerService atm) {
+ void setupActivityManagerService(
+ TestActivityManagerService am, TestActivityTaskManagerService atm) {
atm.setActivityManagerService(am);
- atm.mAmInternal = am.new LocalService();
- am.mAtmInternal = atm.new LocalService();
- am.mUgmInternal = mock(UriGrantsManagerInternal.class);
- atm.mUgmInternal = mock(UriGrantsManagerInternal.class);
+ atm.mAmInternal = am.getLocalService();
+ am.mAtmInternal = atm.getLocalService();
// Makes sure the supervisor is using with the spy object.
atm.mStackSupervisor.setService(atm);
doReturn(mock(IPackageManager.class)).when(am).getPackageManager();
@@ -378,6 +381,8 @@
protected static class TestActivityTaskManagerService extends ActivityTaskManagerService {
private LockTaskController mLockTaskController;
+ private ActivityTaskManagerInternal mInternal;
+ private PackageManagerInternal mPmInternal;
TestActivityTaskManagerService(Context context) {
super(context);
@@ -386,6 +391,7 @@
mSupportsSplitScreenMultiWindow = true;
mSupportsFreeformWindowManagement = true;
mSupportsPictureInPicture = true;
+ mUgmInternal = mock(UriGrantsManagerInternal.class);
}
@Override
@@ -430,16 +436,34 @@
protected ActivityStackSupervisor createTestSupervisor() {
return new TestActivityStackSupervisor(this, mH.getLooper());
}
+
+ ActivityTaskManagerInternal getLocalService() {
+ if (mInternal == null) {
+ mInternal = new ActivityTaskManagerService.LocalService();
+ }
+ return mInternal;
+ }
+
+ PackageManagerInternal getPackageManagerInternalLocked() {
+ if (mPmInternal == null) {
+ mPmInternal = mock(PackageManagerInternal.class);
+ doReturn(false).when(mPmInternal).isPermissionsReviewRequired(anyString(), anyInt());
+ }
+ return mPmInternal;
+ }
}
/**
* An {@link ActivityManagerService} subclass which provides a test
* {@link ActivityStackSupervisor}.
*/
- protected static class TestActivityManagerService extends ActivityManagerService {
+ static class TestActivityManagerService extends ActivityManagerService {
+
+ private ActivityManagerInternal mInternal;
TestActivityManagerService(Context context, TestActivityTaskManagerService atm) {
super(context, atm);
+ mUgmInternal = mock(UriGrantsManagerInternal.class);
}
@Override
@@ -450,6 +474,13 @@
Configuration getGlobalConfiguration() {
return mContext.getResources().getConfiguration();
}
+
+ ActivityManagerInternal getLocalService() {
+ if (mInternal == null) {
+ mInternal = new LocalService();
+ }
+ return mInternal;
+ }
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index 37de795..227a70f 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -115,7 +115,8 @@
mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
mService = spy(new MyTestActivityTaskManagerService(mContext));
- final ActivityManagerService am = spy(new MyTestActivityManagerService(mContext, mService));
+ final TestActivityManagerService am =
+ spy(new MyTestActivityManagerService(mContext, mService));
setupActivityManagerService(am, mService);
mRecentTasks = (TestRecentTasks) mService.getRecentTasks();
mRecentTasks.loadParametersFromResources(mContext.getResources());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
new file mode 100644
index 0000000..14695c5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.hdmi;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.annotation.Nullable;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.os.Looper;
+import android.os.test.TestLooper;
+import android.support.test.filters.SmallTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link ArcTerminationActionFromAvr} */
+@SmallTest
+@RunWith(JUnit4.class)
+public class ArcTerminationActionFromAvrTest {
+
+ private HdmiDeviceInfo mDeviceInfoForTests;
+ private HdmiCecLocalDeviceAudioSystem mHdmiCecLocalDeviceAudioSystem;
+ private ArcTerminationActionFromAvr mAction;
+
+ private TestLooper mTestLooper = new TestLooper();
+ private boolean mSendCecCommandSuccess;
+ private boolean mShouldDispatchReportArcTerminated;
+ private boolean mArcEnabled;
+ private boolean mSetArcStatusCalled;
+
+ @Before
+ public void setUp() {
+ mDeviceInfoForTests = new HdmiDeviceInfo(1000, 1);
+
+ HdmiControlService hdmiControlService =
+ new HdmiControlService(null) {
+ @Override
+ void sendCecCommand(
+ HdmiCecMessage command, @Nullable SendMessageCallback callback) {
+ switch (command.getOpcode()) {
+ case Constants.MESSAGE_TERMINATE_ARC:
+ if (callback != null) {
+ callback.onSendCompleted(
+ mSendCecCommandSuccess
+ ? SendMessageResult.SUCCESS
+ : SendMessageResult.NACK);
+ }
+ if (mShouldDispatchReportArcTerminated) {
+ mHdmiCecLocalDeviceAudioSystem.dispatchMessage(
+ HdmiCecMessageBuilder.buildReportArcTerminated(
+ Constants.ADDR_TV,
+ mHdmiCecLocalDeviceAudioSystem.mAddress));
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unexpected message");
+ }
+ }
+
+ @Override
+ boolean isPowerStandby() {
+ return false;
+ }
+
+ @Override
+ boolean isAddressAllocated() {
+ return true;
+ }
+
+ @Override
+ Looper getServiceLooper() {
+ return mTestLooper.getLooper();
+ }
+ };
+
+ mHdmiCecLocalDeviceAudioSystem =
+ new HdmiCecLocalDeviceAudioSystem(hdmiControlService) {
+ @Override
+ HdmiDeviceInfo getDeviceInfo() {
+ return mDeviceInfoForTests;
+ }
+
+ @Override
+ void setArcStatus(boolean enabled) {
+ mSetArcStatusCalled = true;
+ mArcEnabled = enabled;
+ }
+ };
+ mHdmiCecLocalDeviceAudioSystem.init();
+ Looper looper = mTestLooper.getLooper();
+ hdmiControlService.setIoLooper(looper);
+
+ mArcEnabled = true;
+ mAction = new ArcTerminationActionFromAvr(mHdmiCecLocalDeviceAudioSystem);
+ }
+
+ @Test
+ public void testSendMessage_NotSuccess() {
+ mSendCecCommandSuccess = false;
+ mShouldDispatchReportArcTerminated = false;
+ mSetArcStatusCalled = false;
+ mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
+
+ mTestLooper.dispatchAll();
+ assertThat(mSetArcStatusCalled).isFalse();
+ assertThat(mArcEnabled).isTrue();
+ }
+
+ @Test
+ public void testReportArcTerminated_NotReceived() {
+ mSendCecCommandSuccess = true;
+ mShouldDispatchReportArcTerminated = false;
+ mSetArcStatusCalled = false;
+ mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
+
+ mTestLooper.moveTimeForward(1000);
+ mTestLooper.dispatchAll();
+ assertThat(mSetArcStatusCalled).isFalse();
+ assertThat(mArcEnabled).isTrue();
+ }
+
+ @Test
+ public void testReportArcTerminated_Received() {
+ mSendCecCommandSuccess = true;
+ mShouldDispatchReportArcTerminated = true;
+ mSetArcStatusCalled = false;
+ mHdmiCecLocalDeviceAudioSystem.addAndStartAction(mAction);
+
+ mTestLooper.moveTimeForward(1000);
+ mTestLooper.dispatchAll();
+ assertThat(mSetArcStatusCalled).isTrue();
+ assertThat(mArcEnabled).isFalse();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
index d437ca1..e114e03 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DetectTvSystemAudioModeSupportActionTest.java
@@ -23,16 +23,13 @@
import android.os.Looper;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
-
import com.android.server.hdmi.HdmiCecLocalDeviceAudioSystem.TvSystemAudioModeSupportedCallback;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-/**
- * Tests for {@link DetectTvSystemAudioModeSupportAction} class.
- */
+/** Tests for {@link DetectTvSystemAudioModeSupportAction} class. */
@SmallTest
@RunWith(JUnit4.class)
public class DetectTvSystemAudioModeSupportActionTest {
@@ -49,46 +46,49 @@
@Before
public void SetUp() {
mDeviceInfoForTests = new HdmiDeviceInfo(1001, 1234);
- HdmiControlService hdmiControlService = new HdmiControlService(null) {
+ HdmiControlService hdmiControlService =
+ new HdmiControlService(null) {
- @Override
- void sendCecCommand(HdmiCecMessage command,
- @Nullable SendMessageCallback callback) {
- switch (command.getOpcode()) {
- case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE:
- if (callback != null) {
- callback.onSendCompleted(mSendCecCommandSuccess
- ? SendMessageResult.SUCCESS : SendMessageResult.NACK);
+ @Override
+ void sendCecCommand(
+ HdmiCecMessage command, @Nullable SendMessageCallback callback) {
+ switch (command.getOpcode()) {
+ case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE:
+ if (callback != null) {
+ callback.onSendCompleted(
+ mSendCecCommandSuccess
+ ? SendMessageResult.SUCCESS
+ : SendMessageResult.NACK);
+ }
+ if (mShouldDispatchFeatureAbort) {
+ mHdmiCecLocalDeviceAudioSystem.dispatchMessage(
+ HdmiCecMessageBuilder.buildFeatureAbortCommand(
+ Constants.ADDR_TV,
+ mHdmiCecLocalDeviceAudioSystem.mAddress,
+ Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE,
+ Constants.ABORT_UNRECOGNIZED_OPCODE));
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unexpected message");
}
- if (mShouldDispatchFeatureAbort) {
- mHdmiCecLocalDeviceAudioSystem.dispatchMessage(
- HdmiCecMessageBuilder.buildFeatureAbortCommand(
- Constants.ADDR_TV,
- mHdmiCecLocalDeviceAudioSystem.mAddress,
- Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE,
- Constants.ABORT_UNRECOGNIZED_OPCODE));
- }
- break;
- default:
- throw new IllegalArgumentException("Unexpected message");
- }
- }
+ }
- @Override
- boolean isPowerStandby() {
- return false;
- }
+ @Override
+ boolean isPowerStandby() {
+ return false;
+ }
- @Override
- boolean isAddressAllocated() {
- return true;
- }
+ @Override
+ boolean isAddressAllocated() {
+ return true;
+ }
- @Override
- Looper getServiceLooper() {
- return mTestLooper.getLooper();
- }
- };
+ @Override
+ Looper getServiceLooper() {
+ return mTestLooper.getLooper();
+ }
+ };
mHdmiCecLocalDeviceAudioSystem =
new HdmiCecLocalDeviceAudioSystem(hdmiControlService) {
@Override
@@ -100,13 +100,14 @@
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
- mAction = new DetectTvSystemAudioModeSupportAction(
- mHdmiCecLocalDeviceAudioSystem,
- new TvSystemAudioModeSupportedCallback() {
- public void onResult(boolean supported) {
- mSupported = Boolean.valueOf(supported);
- }
- });
+ mAction =
+ new DetectTvSystemAudioModeSupportAction(
+ mHdmiCecLocalDeviceAudioSystem,
+ new TvSystemAudioModeSupportedCallback() {
+ public void onResult(boolean supported) {
+ mSupported = Boolean.valueOf(supported);
+ }
+ });
mSupported = null;
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java
index 5509935..7484edd 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeNativeWrapper.java
@@ -18,10 +18,10 @@
import android.hardware.hdmi.HdmiPortInfo;
import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.os.MessageQueue;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.hdmi.HdmiCecController.NativeWrapper;
import java.util.ArrayList;
import java.util.List;
-import com.android.internal.annotations.VisibleForTesting;
/** Fake {@link NativeWrapper} useful for testing. */
final class FakeNativeWrapper implements NativeWrapper {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
index 84e1b7e..6cf5f00 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecControllerTest.java
@@ -15,17 +15,6 @@
*/
package com.android.server.hdmi;
-import android.content.Context;
-import android.hardware.hdmi.HdmiPortInfo;
-import android.hardware.tv.cec.V1_0.SendMessageResult;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.os.test.TestLooper;
-import android.support.test.filters.SmallTest;
-import android.util.Log;
-import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
-import com.android.server.hdmi.HdmiCecController.NativeWrapper;
-
import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK;
import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_TV;
@@ -37,14 +26,19 @@
import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
import static junit.framework.Assert.assertEquals;
+
+import android.content.Context;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
+import android.os.Looper;
+import android.os.test.TestLooper;
+import android.support.test.filters.SmallTest;
+import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-/**
- * Tests for {@link com.android.server.hdmi.HdmiCecController} class.
- */
+/** Tests for {@link com.android.server.hdmi.HdmiCecController} class. */
@SmallTest
@RunWith(JUnit4.class)
public class HdmiCecControllerTest {
@@ -71,12 +65,13 @@
private HdmiControlService mHdmiControlService;
private HdmiCecController mHdmiCecController;
private int mLogicalAddress = 16;
- private AllocateAddressCallback mCallback = new AllocateAddressCallback() {
- @Override
- public void onAllocated(int deviceType, int logicalAddress) {
- mLogicalAddress = logicalAddress;
- }
- };
+ private AllocateAddressCallback mCallback =
+ new AllocateAddressCallback() {
+ @Override
+ public void onAllocated(int deviceType, int logicalAddress) {
+ mLogicalAddress = logicalAddress;
+ }
+ };
private Looper mMyLooper;
private TestLooper mTestLooper = new TestLooper();
@@ -86,13 +81,11 @@
mMyLooper = mTestLooper.getLooper();
mHdmiControlService = new MyHdmiControlService(null);
mNativeWrapper = new FakeNativeWrapper();
- mHdmiCecController = HdmiCecController.createWithNativeWrapper(
- mHdmiControlService, mNativeWrapper);
+ mHdmiCecController =
+ HdmiCecController.createWithNativeWrapper(mHdmiControlService, mNativeWrapper);
}
- /**
- * Tests for {@link HdmiCecController#allocateLogicalAddress}
- */
+ /** Tests for {@link HdmiCecController#allocateLogicalAddress} */
@Test
public void testAllocatLogicalAddress_TvDevicePreferredNotOcupied() {
mHdmiCecController.allocateLogicalAddress(DEVICE_TV, ADDR_TV, mCallback);
@@ -128,7 +121,7 @@
@Test
public void testAllocatLogicalAddress_AudioSystemNonPreferredNotOcupied() {
mHdmiCecController.allocateLogicalAddress(
- DEVICE_AUDIO_SYSTEM, ADDR_UNREGISTERED, mCallback);
+ DEVICE_AUDIO_SYSTEM, ADDR_UNREGISTERED, mCallback);
mTestLooper.dispatchAll();
assertEquals(ADDR_AUDIO_SYSTEM, mLogicalAddress);
}
@@ -137,7 +130,7 @@
public void testAllocatLogicalAddress_AudioSystemNonPreferredAllOcupied() {
mNativeWrapper.setPollAddressResponse(ADDR_AUDIO_SYSTEM, SendMessageResult.SUCCESS);
mHdmiCecController.allocateLogicalAddress(
- DEVICE_AUDIO_SYSTEM, ADDR_UNREGISTERED, mCallback);
+ DEVICE_AUDIO_SYSTEM, ADDR_UNREGISTERED, mCallback);
mTestLooper.dispatchAll();
assertEquals(ADDR_UNREGISTERED, mLogicalAddress);
}
@@ -152,8 +145,7 @@
@Test
public void testAllocatLogicalAddress_PlaybackPreferredOcuppied() {
mNativeWrapper.setPollAddressResponse(ADDR_PLAYBACK_1, SendMessageResult.SUCCESS);
- mHdmiCecController.allocateLogicalAddress(
- DEVICE_PLAYBACK, ADDR_PLAYBACK_1, mCallback);
+ mHdmiCecController.allocateLogicalAddress(DEVICE_PLAYBACK, ADDR_PLAYBACK_1, mCallback);
mTestLooper.dispatchAll();
assertEquals(ADDR_PLAYBACK_2, mLogicalAddress);
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index 4745683..0dc5130 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -24,21 +24,22 @@
import android.media.AudioManager;
import android.os.Looper;
+import android.os.SystemProperties;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
-
import com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource;
+import java.util.List;
import java.util.ArrayList;
+import java.util.Collections;
import org.junit.Before;
import org.junit.Test;
+import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@SmallTest
@RunWith(JUnit4.class)
-/**
- * Tests for {@link HdmiCecLocalDeviceAudioSystem} class.
- */
+/** Tests for {@link HdmiCecLocalDeviceAudioSystem} class. */
public class HdmiCecLocalDeviceAudioSystemTest {
private static final String TAG = "HdmiCecLocalDeviceAudioSystemTest";
@@ -55,66 +56,74 @@
@Before
public void SetUp() {
- mHdmiControlService = new HdmiControlService(null) {
- @Override
- AudioManager getAudioManager() {
- return new AudioManager() {
+ mHdmiControlService =
+ new HdmiControlService(null) {
@Override
- public int getStreamVolume(int streamType) {
- switch (streamType) {
- case STREAM_MUSIC:
- return mMusicVolume;
- default:
- return 0;
- }
- }
-
- @Override
- public boolean isStreamMute(int streamType) {
- switch (streamType) {
- case STREAM_MUSIC:
- return mMusicMute;
- default:
- return false;
- }
- }
-
- @Override
- public int getStreamMaxVolume(int streamType) {
- switch (streamType) {
- case STREAM_MUSIC:
- return mMusicMaxVolume;
- default:
- return 100;
- }
- }
-
- @Override
- public void adjustStreamVolume(int streamType, int direction, int flags) {
- switch (streamType) {
- case STREAM_MUSIC:
- if (direction == AudioManager.ADJUST_UNMUTE) {
- mMusicMute = false;
- } else if (direction == AudioManager.ADJUST_MUTE) {
- mMusicMute = true;
+ AudioManager getAudioManager() {
+ return new AudioManager() {
+ @Override
+ public int getStreamVolume(int streamType) {
+ switch (streamType) {
+ case STREAM_MUSIC:
+ return mMusicVolume;
+ default:
+ return 0;
}
- default:
- }
- }
- };
- }
+ }
- @Override
- void wakeUp() {
- }
- };
+ @Override
+ public boolean isStreamMute(int streamType) {
+ switch (streamType) {
+ case STREAM_MUSIC:
+ return mMusicMute;
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public int getStreamMaxVolume(int streamType) {
+ switch (streamType) {
+ case STREAM_MUSIC:
+ return mMusicMaxVolume;
+ default:
+ return 100;
+ }
+ }
+
+ @Override
+ public void adjustStreamVolume(
+ int streamType, int direction, int flags) {
+ switch (streamType) {
+ case STREAM_MUSIC:
+ if (direction == AudioManager.ADJUST_UNMUTE) {
+ mMusicMute = false;
+ } else if (direction == AudioManager.ADJUST_MUTE) {
+ mMusicMute = true;
+ }
+ default:
+ }
+ }
+
+ @Override
+ public void setWiredDeviceConnectionState(
+ int type, int state, String address, String name) {
+ // Do nothing.
+ }
+ };
+ }
+
+ @Override
+ void wakeUp() {}
+ };
+
mMyLooper = mTestLooper.getLooper();
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
mHdmiCecLocalDeviceAudioSystem.init();
mHdmiControlService.setIoLooper(mMyLooper);
mNativeWrapper = new FakeNativeWrapper();
- mHdmiCecController = HdmiCecController.createWithNativeWrapper(
- mHdmiControlService, mNativeWrapper);
+ mHdmiCecController =
+ HdmiCecController.createWithNativeWrapper(mHdmiControlService, mNativeWrapper);
mHdmiControlService.setCecController(mHdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
@@ -123,105 +132,93 @@
// No TV device interacts with AVR so system audio control won't be turned on here
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
mTestLooper.dispatchAll();
+ SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "true");
}
+
@Test
public void handleGiveAudioStatus_volume_10_mute_true() {
mMusicVolume = 10;
mMusicMute = true;
mMusicMaxVolume = 20;
int scaledVolume = VolumeControlAction.scaleToCecVolume(10, mMusicMaxVolume);
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder.buildReportAudioStatus(
- ADDR_AUDIO_SYSTEM, ADDR_TV, scaledVolume, true);
- HdmiCecMessage messageGive = HdmiCecMessageBuilder.buildGiveAudioStatus(
- ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildReportAudioStatus(
+ ADDR_AUDIO_SYSTEM, ADDR_TV, scaledVolume, true);
+ HdmiCecMessage messageGive =
+ HdmiCecMessageBuilder.buildGiveAudioStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveAudioStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
+
@Test
public void handleGiveSystemAudioModeStatus_originalOff() {
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
- .buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
- HdmiCecMessage messageGive = HdmiCecMessageBuilder
- .buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
+ HdmiCecMessage messageGive =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
- @Test
- public void handleRequestArcInitiate() {
- // TODO(b/80296911): Add tests when finishing handler impl.
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
- .buildInitiateArc(ADDR_AUDIO_SYSTEM, ADDR_TV);
- HdmiCecMessage message = HdmiCecMessageBuilder
- .buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
- assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
- .isEqualTo(true);
- mTestLooper.dispatchAll();
- assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- }
- @Test
- public void handleRequestArcTermination() {
- // TODO(b/80297105): Add tests when finishing handler impl.
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
- .buildTerminateArc(ADDR_AUDIO_SYSTEM, ADDR_TV);
- HdmiCecMessage messageRequestOff = HdmiCecMessageBuilder
- .buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
- assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(messageRequestOff))
- .isEqualTo(true);
- mTestLooper.dispatchAll();
- assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- }
+
+ @Ignore("b/80297700")
@Test
public void handleSetSystemAudioMode_setOn_orignalOff() {
mMusicMute = true;
- HdmiCecMessage messageSet = HdmiCecMessageBuilder
- .buildSetSystemAudioMode(ADDR_TV, ADDR_AUDIO_SYSTEM, true);
- HdmiCecMessage messageGive = HdmiCecMessageBuilder
- .buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage messageSet =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(ADDR_TV, ADDR_AUDIO_SYSTEM, true);
+ HdmiCecMessage messageGive =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
// Check if originally off
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
- .buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
// Check if correctly turned on
- expectedMessage = HdmiCecMessageBuilder
- .buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, true);
+ expectedMessage =
+ HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, true);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleSetSystemAudioMode(messageSet))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- assertThat(mMusicMute).isEqualTo(false);
+ assertThat(mMusicMute).isFalse();
}
+
+ @Ignore("b/80297700")
@Test
public void handleSystemAudioModeRequest_turnOffByTv() {
- assertThat(mMusicMute).isEqualTo(false);
+ assertThat(mMusicMute).isFalse();
// Check if feature correctly turned off
- HdmiCecMessage messageGive = HdmiCecMessageBuilder
- .buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
- HdmiCecMessage messageRequestOff = HdmiCecMessageBuilder
- .buildSystemAudioModeRequest(ADDR_TV, ADDR_AUDIO_SYSTEM, 2, false);
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
- .buildSetSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
+ HdmiCecMessage messageGive =
+ HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage messageRequestOff =
+ HdmiCecMessageBuilder.buildSystemAudioModeRequest(
+ ADDR_TV, ADDR_AUDIO_SYSTEM, 2, false);
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleSystemAudioModeRequest(messageRequestOff))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- expectedMessage = HdmiCecMessageBuilder
- .buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
+ expectedMessage =
+ HdmiCecMessageBuilder.buildReportSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_TV, false);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleGiveSystemAudioModeStatus(messageGive))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- assertThat(mMusicMute).isEqualTo(true);
+ assertThat(mMusicMute).isTrue();
}
+
+ @Ignore("b/80297700")
@Test
public void onStandbyAudioSystem_currentSystemAudioControlOn() {
// Set system audio control on first
@@ -229,80 +226,94 @@
// Check if standby correctly turns off the feature
mHdmiCecLocalDeviceAudioSystem.onStandby(false, STANDBY_SCREEN_OFF);
mTestLooper.dispatchAll();
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
- .buildSetSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
- assertThat(mMusicMute).isEqualTo(true);
+ assertThat(mMusicMute).isTrue();
}
+
@Test
public void systemAudioControlOnPowerOn_alwaysOn() {
- mHdmiCecLocalDeviceAudioSystem.removeAction(
- SystemAudioInitiationActionFromAvr.class);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(SystemAudioInitiationActionFromAvr.class);
mHdmiCecLocalDeviceAudioSystem.systemAudioControlOnPowerOn(
Constants.ALWAYS_SYSTEM_AUDIO_CONTROL_ON_POWER_ON, true);
- assertThat(mHdmiCecLocalDeviceAudioSystem
- .getActions(SystemAudioInitiationActionFromAvr.class)).isNotEmpty();
+ assertThat(
+ mHdmiCecLocalDeviceAudioSystem.getActions(
+ SystemAudioInitiationActionFromAvr.class))
+ .isNotEmpty();
}
+
@Test
public void systemAudioControlOnPowerOn_neverOn() {
- mHdmiCecLocalDeviceAudioSystem.removeAction(
- SystemAudioInitiationActionFromAvr.class);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(SystemAudioInitiationActionFromAvr.class);
mHdmiCecLocalDeviceAudioSystem.systemAudioControlOnPowerOn(
Constants.NEVER_SYSTEM_AUDIO_CONTROL_ON_POWER_ON, false);
- assertThat(mHdmiCecLocalDeviceAudioSystem
- .getActions(SystemAudioInitiationActionFromAvr.class)).isEmpty();
+ assertThat(
+ mHdmiCecLocalDeviceAudioSystem.getActions(
+ SystemAudioInitiationActionFromAvr.class))
+ .isEmpty();
}
+
@Test
public void systemAudioControlOnPowerOn_useLastState_off() {
- mHdmiCecLocalDeviceAudioSystem.removeAction(
- SystemAudioInitiationActionFromAvr.class);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(SystemAudioInitiationActionFromAvr.class);
mHdmiCecLocalDeviceAudioSystem.systemAudioControlOnPowerOn(
Constants.USE_LAST_STATE_SYSTEM_AUDIO_CONTROL_ON_POWER_ON, false);
- assertThat(mHdmiCecLocalDeviceAudioSystem
- .getActions(SystemAudioInitiationActionFromAvr.class)).isEmpty();
+ assertThat(
+ mHdmiCecLocalDeviceAudioSystem.getActions(
+ SystemAudioInitiationActionFromAvr.class))
+ .isEmpty();
}
+
@Test
public void systemAudioControlOnPowerOn_useLastState_on() {
- mHdmiCecLocalDeviceAudioSystem.removeAction(
- SystemAudioInitiationActionFromAvr.class);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(SystemAudioInitiationActionFromAvr.class);
mHdmiCecLocalDeviceAudioSystem.systemAudioControlOnPowerOn(
Constants.USE_LAST_STATE_SYSTEM_AUDIO_CONTROL_ON_POWER_ON, true);
- assertThat(mHdmiCecLocalDeviceAudioSystem
- .getActions(SystemAudioInitiationActionFromAvr.class)).isNotEmpty();
+ assertThat(
+ mHdmiCecLocalDeviceAudioSystem.getActions(
+ SystemAudioInitiationActionFromAvr.class))
+ .isNotEmpty();
}
+
@Test
public void handleActiveSource_updateActiveSource() {
- HdmiCecMessage message = HdmiCecMessageBuilder
- .buildActiveSource(ADDR_TV, 0x0000);
+ HdmiCecMessage message = HdmiCecMessageBuilder.buildActiveSource(ADDR_TV, 0x0000);
ActiveSource expectedActiveSource = new ActiveSource(ADDR_TV, 0x0000);
assertThat(mHdmiCecLocalDeviceAudioSystem.handleActiveSource(message))
- .isEqualTo(true);
+ .isTrue();
mTestLooper.dispatchAll();
assertThat(mHdmiCecLocalDeviceAudioSystem.getActiveSource().equals(expectedActiveSource))
- .isEqualTo(true);
+ .isTrue();
}
+
@Test
public void terminateSystemAudioMode_systemAudioModeOff() {
mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(false);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(false);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isFalse();
mMusicMute = false;
- HdmiCecMessage message = HdmiCecMessageBuilder
- .buildSetSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
mHdmiCecLocalDeviceAudioSystem.terminateSystemAudioMode();
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(false);
- assertThat(mMusicMute).isEqualTo(false);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isFalse();
+ assertThat(mMusicMute).isFalse();
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(message);
}
+
+ @Ignore("b/80297700")
@Test
public void terminateSystemAudioMode_systemAudioModeOn() {
mHdmiCecLocalDeviceAudioSystem.setSystemAudioMode(true);
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(true);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isTrue();
mMusicMute = false;
- HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
- .buildSetSystemAudioMode(ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
+ HdmiCecMessage expectedMessage =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ ADDR_AUDIO_SYSTEM, ADDR_BROADCAST, false);
mHdmiCecLocalDeviceAudioSystem.terminateSystemAudioMode();
- assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isEqualTo(false);
- assertThat(mMusicMute).isEqualTo(true);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated()).isFalse();
+ assertThat(mMusicMute).isTrue();
mTestLooper.dispatchAll();
assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
@@ -312,7 +323,7 @@
int targetPhysicalAddress = 0x1000;
mNativeWrapper.setPhysicalAddress(0x1000);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(true);
+ .isTrue();
}
@Test
@@ -320,7 +331,7 @@
int targetPhysicalAddress = 0x1100;
mNativeWrapper.setPhysicalAddress(0x1000);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(true);
+ .isTrue();
}
@Test
@@ -328,21 +339,104 @@
int targetPhysicalAddress = 0x3000;
mNativeWrapper.setPhysicalAddress(0x2000);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
targetPhysicalAddress = 0x2200;
mNativeWrapper.setPhysicalAddress(0x3300);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
targetPhysicalAddress = 0x2213;
mNativeWrapper.setPhysicalAddress(0x2212);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
targetPhysicalAddress = 0x2340;
mNativeWrapper.setPhysicalAddress(0x2310);
assertThat(mHdmiCecLocalDeviceAudioSystem.isPhysicalAddressMeOrBelow(targetPhysicalAddress))
- .isEqualTo(false);
+ .isFalse();
+ }
+
+ @Test
+ public void handleRequestArcInitiate_isNotDirectConnectedToTv() {
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
+ .buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV,
+ Constants.MESSAGE_REQUEST_ARC_INITIATION,
+ Constants.ABORT_NOT_IN_CORRECT_MODE);
+ mNativeWrapper.setPhysicalAddress(0x1100);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
+ }
+
+ @Test
+ public void handleRequestArcInitiate_startArcInitiationActionFromAvr() {
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ mNativeWrapper.setPhysicalAddress(0x1000);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(
+ ArcInitiationActionFromAvr.class);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getActions(ArcInitiationActionFromAvr.class)).isNotEmpty();
+ }
+
+ @Test
+ public void handleRequestArcTerminate_arcIsOn_startTerminationActionFromAvr() {
+ mHdmiCecLocalDeviceAudioSystem.setArcStatus(true);
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isTrue();
+
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ mHdmiCecLocalDeviceAudioSystem.removeAction(
+ ArcTerminationActionFromAvr.class);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiCecLocalDeviceAudioSystem
+ .getActions(ArcTerminationActionFromAvr.class)).isNotEmpty();
+ }
+
+ @Test
+ public void handleRequestArcTerminate_arcIsNotOn() {
+ assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcTermination(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
+ .buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV,
+ Constants.MESSAGE_REQUEST_ARC_TERMINATION,
+ Constants.ABORT_NOT_IN_CORRECT_MODE);
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcTermination(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
+ }
+
+ @Test
+ public void handleRequestArcInit_arcIsNotSupported() {
+ HdmiCecMessage message = HdmiCecMessageBuilder
+ .buildRequestArcInitiation(ADDR_TV, ADDR_AUDIO_SYSTEM);
+ HdmiCecMessage expectedMessage = HdmiCecMessageBuilder
+ .buildFeatureAbortCommand(
+ ADDR_AUDIO_SYSTEM, ADDR_TV,
+ Constants.MESSAGE_REQUEST_ARC_INITIATION,
+ Constants.ABORT_UNRECOGNIZED_OPCODE);
+ SystemProperties.set(Constants.PROPERTY_ARC_SUPPORT, "false");
+
+ assertThat(mHdmiCecLocalDeviceAudioSystem.handleRequestArcInitiate(message))
+ .isTrue();
+ mTestLooper.dispatchAll();
+ assertThat(mNativeWrapper.getResultMessages()).contains(expectedMessage);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index 833ffa6..3cd8481 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -27,13 +27,8 @@
import static junit.framework.Assert.assertTrue;
import android.hardware.hdmi.HdmiControlManager;
-import android.hardware.hdmi.HdmiPortInfo;
-import android.os.PowerManager;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
-import android.os.MessageQueue;
-import com.android.server.hdmi.HdmiCecController.NativeWrapper;
-import junit.framework.Assert;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
@@ -42,20 +37,19 @@
@SmallTest
@RunWith(JUnit4.class)
-/**
- * Tests for {@link HdmiCecLocalDevice} class.
- */
+/** Tests for {@link HdmiCecLocalDevice} class. */
public class HdmiCecLocalDeviceTest {
-
private static int SendCecCommandFactory(int srcAddress, int dstAddress, byte[] body) {
- switch(body[0] & 0xFF) {
- /** {@link Constants#MESSAGE_GIVE_PHYSICAL_ADDRESS} */
+ switch (body[0] & 0xFF) {
+ /** {@link Constants#MESSAGE_GIVE_PHYSICAL_ADDRESS} */
case MESSAGE_REPORT_PHYSICAL_ADDRESS:
case MESSAGE_DEVICE_VENDOR_ID:
- return srcAddress == mSrcAddr &&
- dstAddress == mDesAddr &&
- Arrays.equals(Arrays.copyOfRange(body, 1, body.length), param)? 0 : 1;
+ return srcAddress == mSrcAddr
+ && dstAddress == mDesAddr
+ && Arrays.equals(Arrays.copyOfRange(body, 1, body.length), param)
+ ? 0
+ : 1;
default:
return 1;
}
@@ -63,15 +57,12 @@
private class MyHdmiCecLocalDevice extends HdmiCecLocalDevice {
-
protected MyHdmiCecLocalDevice(HdmiControlService service, int deviceType) {
super(service, deviceType);
}
@Override
- protected void onAddressAllocated(int logicalAddress, int reason) {
-
- }
+ protected void onAddressAllocated(int logicalAddress, int reason) {}
@Override
protected int getPreferredAddress() {
@@ -79,9 +70,7 @@
}
@Override
- protected void setPreferredAddress(int addr) {
-
- }
+ protected void setPreferredAddress(int addr) {}
}
private MyHdmiCecLocalDevice mHdmiLocalDevice;
@@ -100,42 +89,48 @@
@Before
public void SetUp() {
- mHdmiControlService = new HdmiControlService(null) {
- @Override
- boolean isControlEnabled() {
- return isControlEnabled;
- }
+ mHdmiControlService =
+ new HdmiControlService(null) {
+ @Override
+ boolean isControlEnabled() {
+ return isControlEnabled;
+ }
- @Override
- boolean isPowerOnOrTransient() {
- return mPowerStatus == HdmiControlManager.POWER_STATUS_ON
- || mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
- }
+ @Override
+ boolean isPowerOnOrTransient() {
+ return mPowerStatus == HdmiControlManager.POWER_STATUS_ON
+ || mPowerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON;
+ }
- @Override
- void standby() {
- mStandbyMessageReceived = true;
- }
- };
+ @Override
+ void standby() {
+ mStandbyMessageReceived = true;
+ }
+ };
mHdmiControlService.setIoLooper(mTestLooper.getLooper());
- mHdmiCecController = HdmiCecController.createWithNativeWrapper(
- mHdmiControlService, new FakeNativeWrapper());
+ mHdmiCecController =
+ HdmiCecController.createWithNativeWrapper(
+ mHdmiControlService, new FakeNativeWrapper());
mHdmiControlService.setCecController(mHdmiCecController);
- mHdmiLocalDevice = new MyHdmiCecLocalDevice(
- mHdmiControlService, DEVICE_TV);
- mMessageValidator = new HdmiCecMessageValidator(mHdmiControlService){
- @Override
- int isValid(HdmiCecMessage message) {
- return HdmiCecMessageValidator.OK;
- }
- };
+ mHdmiLocalDevice = new MyHdmiCecLocalDevice(mHdmiControlService, DEVICE_TV);
+ mMessageValidator =
+ new HdmiCecMessageValidator(mHdmiControlService) {
+ @Override
+ int isValid(HdmiCecMessage message) {
+ return HdmiCecMessageValidator.OK;
+ }
+ };
mHdmiControlService.setMessageValidator(mMessageValidator);
}
@Test
public void dispatchMessage_desNotValid() {
- HdmiCecMessage msg = new HdmiCecMessage(
- ADDR_TV, ADDR_TV, Constants.MESSAGE_CEC_VERSION, HdmiCecMessage.EMPTY_PARAM);
+ HdmiCecMessage msg =
+ new HdmiCecMessage(
+ ADDR_TV,
+ ADDR_TV,
+ Constants.MESSAGE_CEC_VERSION,
+ HdmiCecMessage.EMPTY_PARAM);
boolean handleResult = mHdmiLocalDevice.dispatchMessage(msg);
assertFalse(handleResult);
}
@@ -144,18 +139,19 @@
public void handleGivePhysicalAddress_success() {
mSrcAddr = ADDR_UNREGISTERED;
mDesAddr = ADDR_BROADCAST;
- param = new byte[] {
- (byte) ((mPhysicalAddr >> 8) & 0xFF),
- (byte) (mPhysicalAddr & 0xFF),
- (byte) (DEVICE_TV & 0xFF)
- };
+ param =
+ new byte[] {
+ (byte) ((mPhysicalAddr >> 8) & 0xFF),
+ (byte) (mPhysicalAddr & 0xFF),
+ (byte) (DEVICE_TV & 0xFF)
+ };
callbackResult = -1;
- boolean handleResult = mHdmiLocalDevice.handleGivePhysicalAddress(
- (int finalResult) -> callbackResult = finalResult);
+ boolean handleResult =
+ mHdmiLocalDevice.handleGivePhysicalAddress(
+ (int finalResult) -> callbackResult = finalResult);
mTestLooper.dispatchAll();
/**
- * Test if CecMessage is sent successfully
- * SendMessageResult#SUCCESS is defined in HAL as 0
+ * Test if CecMessage is sent successfully SendMessageResult#SUCCESS is defined in HAL as 0
*/
assertEquals(0, callbackResult);
assertTrue(handleResult);
@@ -166,14 +162,10 @@
mSrcAddr = ADDR_UNREGISTERED;
mDesAddr = ADDR_BROADCAST;
/** nativeGetVendorId returns 0 */
- param = new byte[] {
- (byte) ((0 >> 8) & 0xFF),
- (byte) (0 & 0xFF),
- (byte) (0 & 0xFF)
- };
+ param = new byte[] {(byte) ((0 >> 8) & 0xFF), (byte) (0 & 0xFF), (byte) (0 & 0xFF)};
callbackResult = -1;
mHdmiLocalDevice.handleGiveDeviceVendorId(
- (int finalResult) -> callbackResult = finalResult);
+ (int finalResult) -> callbackResult = finalResult);
mTestLooper.dispatchAll();
assertEquals(0, callbackResult);
}
@@ -184,7 +176,7 @@
isControlEnabled = true;
assertFalse(mStandbyMessageReceived);
mHdmiLocalDevice.handleStandby(
- HdmiCecMessageBuilder.buildStandby(ADDR_TV, ADDR_AUDIO_SYSTEM));
+ HdmiCecMessageBuilder.buildStandby(ADDR_TV, ADDR_AUDIO_SYSTEM));
assertTrue(mStandbyMessageReceived);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java
index a7618bf..1ca48d4 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecMessageBuilderTest.java
@@ -15,8 +15,9 @@
*/
package com.android.server.hdmi;
-import static com.android.server.hdmi.Constants.ADDR_BROADCAST;
+import static com.android.server.hdmi.Constants.ADDR_AUDIO_SYSTEM;
import static com.android.server.hdmi.Constants.ADDR_PLAYBACK_1;
+import static com.android.server.hdmi.Constants.ADDR_TV;
import static com.google.common.truth.Truth.assertThat;
import android.hardware.hdmi.HdmiDeviceInfo;
@@ -35,12 +36,33 @@
HdmiCecMessage message =
HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
ADDR_PLAYBACK_1, 0x1234, HdmiDeviceInfo.DEVICE_PLAYBACK);
- assertThat(message)
- .isEqualTo(
- new HdmiCecMessage(
- ADDR_PLAYBACK_1,
- ADDR_BROADCAST,
- Constants.MESSAGE_REPORT_PHYSICAL_ADDRESS,
- new byte[] {0x12, 0x34, 0x04}));
+ assertThat(message).isEqualTo(buildMessage("4f:84:12:34:04"));
+ }
+
+ @Test
+ public void buildRequestShortAudioDescriptor() {
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildRequestShortAudioDescriptor(
+ ADDR_TV,
+ ADDR_AUDIO_SYSTEM,
+ new int[] {Constants.AUDIO_CODEC_AAC, Constants.AUDIO_CODEC_LPCM});
+ assertThat(message).isEqualTo(buildMessage("05:A4:06:01"));
+ }
+
+ /**
+ * Build a CEC message from a hex byte string with bytes separated by {@code :}.
+ *
+ * <p>This format is used by both cec-client and www.cec-o-matic.com
+ */
+ private static HdmiCecMessage buildMessage(String message) {
+ String[] parts = message.split(":");
+ int src = Integer.parseInt(parts[0].substring(0, 1), 16);
+ int dest = Integer.parseInt(parts[0].substring(1, 2), 16);
+ int opcode = Integer.parseInt(parts[1], 16);
+ byte[] params = new byte[parts.length - 2];
+ for (int i = 0; i < params.length; i++) {
+ params[i] = Byte.parseByte(parts[i + 2], 16);
+ }
+ return new HdmiCecMessage(src, dest, opcode, params);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 90ad349..7de637b 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -30,9 +30,7 @@
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-/**
- * Tests for {@link HdmiControlService} class.
- */
+/** Tests for {@link HdmiControlService} class. */
@SmallTest
@RunWith(JUnit4.class)
public class HdmiControlServiceTest {
@@ -48,9 +46,7 @@
}
@Override
- protected void onAddressAllocated(int logicalAddress, int reason) {
-
- }
+ protected void onAddressAllocated(int logicalAddress, int reason) {}
@Override
protected int getPreferredAddress() {
@@ -58,9 +54,7 @@
}
@Override
- protected void setPreferredAddress(int addr) {
-
- }
+ protected void setPreferredAddress(int addr) {}
@Override
protected boolean canGoToStandby() {
@@ -68,8 +62,8 @@
}
@Override
- protected void disableDevice(boolean initiatedByCec,
- final PendingActionClearedCallback originalCallback) {
+ protected void disableDevice(
+ boolean initiatedByCec, final PendingActionClearedCallback originalCallback) {
mIsDisabled = true;
originalCallback.onCleared(this);
}
@@ -105,26 +99,26 @@
@Before
public void SetUp() {
- mHdmiControlService = new HdmiControlService(null) {
- @Override
- boolean isStandbyMessageReceived() {
- return mStandbyMessageReceived;
- }
- };
+ mHdmiControlService =
+ new HdmiControlService(null) {
+ @Override
+ boolean isStandbyMessageReceived() {
+ return mStandbyMessageReceived;
+ }
+ };
mMyLooper = mTestLooper.getLooper();
- mMyAudioSystemDevice = new HdmiCecLocalDeviceMyDevice(
- mHdmiControlService, DEVICE_AUDIO_SYSTEM);
- mMyPlaybackDevice = new HdmiCecLocalDeviceMyDevice(
- mHdmiControlService, DEVICE_PLAYBACK);
+ mMyAudioSystemDevice =
+ new HdmiCecLocalDeviceMyDevice(mHdmiControlService, DEVICE_AUDIO_SYSTEM);
+ mMyPlaybackDevice = new HdmiCecLocalDeviceMyDevice(mHdmiControlService, DEVICE_PLAYBACK);
mMyAudioSystemDevice.init();
mMyPlaybackDevice.init();
mHdmiControlService.setIoLooper(mMyLooper);
mNativeWrapper = new FakeNativeWrapper();
- mHdmiCecController = HdmiCecController.createWithNativeWrapper(
- mHdmiControlService, mNativeWrapper);
+ mHdmiCecController =
+ HdmiCecController.createWithNativeWrapper(mHdmiControlService, mNativeWrapper);
mHdmiControlService.setCecController(mHdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index a1614f2..e6ff143 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -26,15 +26,12 @@
import android.os.Looper;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
-
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-/**
- * Tests for {@link SystemAudioInitiationActionFromAvr}
- */
+/** Tests for {@link SystemAudioInitiationActionFromAvr} */
@SmallTest
@RunWith(JUnit4.class)
public class SystemAudioInitiationActionFromAvrTest {
@@ -54,88 +51,86 @@
@Before
public void SetUp() {
mDeviceInfoForTests = new HdmiDeviceInfo(1001, 1234);
- HdmiControlService hdmiControlService = new HdmiControlService(null) {
-
- @Override
- void sendCecCommand(HdmiCecMessage command,
- @Nullable SendMessageCallback callback) {
- switch (command.getOpcode()) {
- case Constants.MESSAGE_REQUEST_ACTIVE_SOURCE:
- mMsgRequestActiveSourceCount++;
- if (mTryCountBeforeSucceed >= mMsgRequestActiveSourceCount
- && callback != null) {
- callback.onSendCompleted(SendMessageResult.NACK);
- break;
- }
- if (mShouldDispatchActiveSource) {
- mHdmiCecLocalDeviceAudioSystem.dispatchMessage(
- HdmiCecMessageBuilder.buildActiveSource(
- Constants.ADDR_TV, 1002));
- }
- break;
- case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE:
- mMsgSetSystemAudioModeCount++;
- if (mTryCountBeforeSucceed >= mMsgSetSystemAudioModeCount
- && callback != null) {
- callback.onSendCompleted(SendMessageResult.NACK);
- }
- break;
- default:
- throw new IllegalArgumentException("Unexpected message");
- }
- }
-
- @Override
- AudioManager getAudioManager() {
- return new AudioManager() {
+ HdmiControlService hdmiControlService =
+ new HdmiControlService(null) {
@Override
- public int setHdmiSystemAudioSupported(boolean on) {
- return 0;
+ void sendCecCommand(
+ HdmiCecMessage command, @Nullable SendMessageCallback callback) {
+ switch (command.getOpcode()) {
+ case Constants.MESSAGE_REQUEST_ACTIVE_SOURCE:
+ mMsgRequestActiveSourceCount++;
+ if (mTryCountBeforeSucceed >= mMsgRequestActiveSourceCount
+ && callback != null) {
+ callback.onSendCompleted(SendMessageResult.NACK);
+ break;
+ }
+ if (mShouldDispatchActiveSource) {
+ mHdmiCecLocalDeviceAudioSystem.dispatchMessage(
+ HdmiCecMessageBuilder.buildActiveSource(
+ Constants.ADDR_TV, 1002));
+ }
+ break;
+ case Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE:
+ mMsgSetSystemAudioModeCount++;
+ if (mTryCountBeforeSucceed >= mMsgSetSystemAudioModeCount
+ && callback != null) {
+ callback.onSendCompleted(SendMessageResult.NACK);
+ }
+ break;
+ default:
+ throw new IllegalArgumentException("Unexpected message");
+ }
}
@Override
- public int getStreamVolume(int streamType) {
- return 0;
+ AudioManager getAudioManager() {
+ return new AudioManager() {
+
+ @Override
+ public int setHdmiSystemAudioSupported(boolean on) {
+ return 0;
+ }
+
+ @Override
+ public int getStreamVolume(int streamType) {
+ return 0;
+ }
+
+ @Override
+ public boolean isStreamMute(int streamType) {
+ return false;
+ }
+
+ @Override
+ public int getStreamMaxVolume(int streamType) {
+ return 100;
+ }
+
+ @Override
+ public void adjustStreamVolume(
+ int streamType, int direction, int flags) {}
+ };
}
@Override
- public boolean isStreamMute(int streamType) {
+ boolean isPowerStandby() {
return false;
}
@Override
- public int getStreamMaxVolume(int streamType) {
- return 100;
+ boolean isAddressAllocated() {
+ return true;
}
@Override
- public void adjustStreamVolume(int streamType, int direction, int flags) {
+ void wakeUp() {}
+ @Override
+ int getPhysicalAddress() {
+ return 0;
}
};
- }
-
- @Override
- boolean isPowerStandby() {
- return false;
- }
-
- @Override
- boolean isAddressAllocated() {
- return true;
- }
-
- @Override
- void wakeUp() {
-
- }
-
- @Override
- int getPhysicalAddress() {
- return 0;
- }
- };
mHdmiCecLocalDeviceAudioSystem =
new HdmiCecLocalDeviceAudioSystem(hdmiControlService) {
@Override
@@ -210,7 +205,6 @@
assertTrue(mHdmiCecLocalDeviceAudioSystem.isSystemAudioActivated());
assertThat(mHdmiCecLocalDeviceAudioSystem.mActiveSource.physicalAddress).isEqualTo(1002);
-
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
index 1d37802..ef87f9d 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
@@ -55,6 +55,7 @@
import com.android.server.policy.keyguard.KeyguardServiceDelegate;
import com.android.server.wm.DisplayFrames;
+import com.android.server.wm.WindowTestUtils.TestDisplayContent;
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Before;
@@ -123,7 +124,6 @@
mNavigationBar.attrs.gravity = Gravity.BOTTOM;
mPolicy.addWindow(mNavigationBar);
- mPolicy.mHasNavigationBar = true;
mPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT;
}
@@ -245,12 +245,10 @@
policy[0].mAccessibilityManager = new AccessibilityManager(context,
mock(IAccessibilityManager.class), UserHandle.USER_CURRENT);
policy[0].mSystemGestures = mock(SystemGesturesPointerEventListener.class);
- policy[0].mNavigationBarCanMove = true;
- policy[0].mPortraitRotation = ROTATION_0;
- policy[0].mLandscapeRotation = ROTATION_90;
- policy[0].mUpsideDownRotation = ROTATION_180;
- policy[0].mSeascapeRotation = ROTATION_270;
- policy[0].onConfigurationChanged();
+
+ final TestDisplayContent displayContent = TestDisplayContent.create(context);
+ policy[0].setDefaultDisplay(displayContent);
+ policy[0].onConfigurationChanged(displayContent);
});
return policy[0];
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
new file mode 100644
index 0000000..c3907ff
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.SurfaceControl.Transaction;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.SurfaceControl;
+
+import com.android.server.wm.WindowTestUtils.TestAppWindowToken;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Animation related tests for the {@link AppWindowToken} class.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:com.android.server.wm.AppWindowTokenAnimationTests
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class AppWindowTokenAnimationTests extends WindowTestsBase {
+
+ private TestAppWindowToken mToken;
+
+ @Mock
+ private Transaction mTransaction;
+ @Mock
+ private AnimationAdapter mSpec;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ MockitoAnnotations.initMocks(this);
+
+ mToken = createTestAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_STANDARD);
+ mToken.setPendingTransaction(mTransaction);
+ }
+
+ @Test
+ public void clipAfterAnim_boundsLayerIsCreated() throws Exception {
+ mToken.mNeedsAnimationBoundsLayer = true;
+
+ mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+ verify(mTransaction).reparent(eq(mToken.getSurfaceControl()),
+ eq(mToken.mSurfaceAnimator.mLeash.getHandle()));
+ verify(mTransaction).reparent(eq(mToken.mSurfaceAnimator.mLeash),
+ eq(mToken.mAnimationBoundsLayer.getHandle()));
+ }
+
+ @Test
+ public void clipAfterAnim_boundsLayerIsDestroyed() throws Exception {
+ mToken.mNeedsAnimationBoundsLayer = true;
+ mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+ final SurfaceControl leash = mToken.mSurfaceAnimator.mLeash;
+ final SurfaceControl animationBoundsLayer = mToken.mAnimationBoundsLayer;
+ final ArgumentCaptor<SurfaceAnimator.OnAnimationFinishedCallback> callbackCaptor =
+ ArgumentCaptor.forClass(
+ SurfaceAnimator.OnAnimationFinishedCallback.class);
+ verify(mSpec).startAnimation(any(), any(), callbackCaptor.capture());
+
+ callbackCaptor.getValue().onAnimationFinished(mSpec);
+ verify(mTransaction).destroy(eq(leash));
+ verify(mTransaction).destroy(eq(animationBoundsLayer));
+ assertThat(mToken.mNeedsAnimationBoundsLayer).isFalse();
+ }
+
+ @Test
+ public void clipAfterAnimCancelled_boundsLayerIsDestroyed() throws Exception {
+ mToken.mNeedsAnimationBoundsLayer = true;
+ mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+ final SurfaceControl leash = mToken.mSurfaceAnimator.mLeash;
+ final SurfaceControl animationBoundsLayer = mToken.mAnimationBoundsLayer;
+
+ mToken.mSurfaceAnimator.cancelAnimation();
+ verify(mTransaction).destroy(eq(leash));
+ verify(mTransaction).destroy(eq(animationBoundsLayer));
+ assertThat(mToken.mNeedsAnimationBoundsLayer).isFalse();
+ }
+
+ @Test
+ public void clipNoneAnim_boundsLayerIsNotCreated() throws Exception {
+ mToken.mNeedsAnimationBoundsLayer = false;
+
+ mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
+ verify(mTransaction).reparent(eq(mToken.getSurfaceControl()),
+ eq(mToken.mSurfaceAnimator.mLeash.getHandle()));
+ assertThat(mToken.mAnimationBoundsLayer).isNull();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index f6599dc..e8d8022 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -42,6 +42,10 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
/**
* Tests for the {@link AppWindowToken} class.
*
@@ -162,6 +166,9 @@
sWm.mDisplayReady = true;
sWm.mDisplayEnabled = true;
+ final DisplayRotation spiedRotation = spy(mDisplayContent.getDisplayRotation());
+ mDisplayContent.setDisplayRotation(spiedRotation);
+
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
TYPE_BASE_APPLICATION);
attrs.setTitle("AppWindow");
@@ -169,20 +176,21 @@
mToken.addWindow(appWindow);
// Set initial orientation and update.
- performRotation(Surface.ROTATION_90);
+ performRotation(spiedRotation, Surface.ROTATION_90);
appWindow.resizeReported = false;
// Update the rotation to perform 180 degree rotation and check that resize was reported.
- performRotation(Surface.ROTATION_270);
+ performRotation(spiedRotation, Surface.ROTATION_270);
assertTrue(appWindow.resizeReported);
+
appWindow.removeImmediately();
}
- private void performRotation(int rotationToReport) {
- ((TestWindowManagerPolicy) sWm.mPolicy).rotationToReport = rotationToReport;
+ private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
+ doReturn(rotationToReport).when(spiedRotation).rotationForOrientation(anyInt(), anyInt());
sWm.updateRotation(false, false);
- // Simulate animator finishing orientation change
- sWm.mRoot.mOrientationChangeComplete = true;
+ // Prevent the next rotation from being deferred by animation.
+ sWm.mAnimator.setScreenRotationAnimationLocked(mDisplayContent.getDisplayId(), null);
sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 4e9894b..ef0e27b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -394,7 +394,8 @@
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
final Task task = createTaskInStack(alwaysOnTopStack, 0 /* userId */);
alwaysOnTopStack.setAlwaysOnTop(true);
- mDisplayContent.positionStackAt(POSITION_TOP, alwaysOnTopStack);
+ mDisplayContent.positionStackAt(POSITION_TOP, alwaysOnTopStack,
+ false /* includingParents */);
assertTrue(alwaysOnTopStack.isAlwaysOnTop());
// Ensure always on top state is synced to the children of the stack.
assertTrue(alwaysOnTopStack.getTopChild().isAlwaysOnTop());
@@ -408,7 +409,8 @@
final TaskStack anotherAlwaysOnTopStack = createStackControllerOnStackOnDisplay(
WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
anotherAlwaysOnTopStack.setAlwaysOnTop(true);
- mDisplayContent.positionStackAt(POSITION_TOP, anotherAlwaysOnTopStack);
+ mDisplayContent.positionStackAt(POSITION_TOP, anotherAlwaysOnTopStack,
+ false /* includingParents */);
assertTrue(anotherAlwaysOnTopStack.isAlwaysOnTop());
int topPosition = mDisplayContent.getStacks().size() - 1;
// Ensure the new alwaysOnTop stack is put below the pinned stack, but on top of the
@@ -424,7 +426,8 @@
assertEquals(nonAlwaysOnTopStack, mDisplayContent.getStacks().get(topPosition - 3));
anotherAlwaysOnTopStack.setAlwaysOnTop(false);
- mDisplayContent.positionStackAt(POSITION_TOP, anotherAlwaysOnTopStack);
+ mDisplayContent.positionStackAt(POSITION_TOP, anotherAlwaysOnTopStack,
+ false /* includingParents */);
assertFalse(anotherAlwaysOnTopStack.isAlwaysOnTop());
// Ensure, when always on top is turned off for a stack, the stack is put just below all
// other always on top stacks.
diff --git a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
index a2ccee4..bfc99c8 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -255,16 +255,32 @@
* Asserts the top inset of {@param activity} is equal to {@param expected} waiting as needed.
*/
private void assertTopInsetEquals(Activity activity, int expected) throws Exception {
- waitFor(() -> getInsets(activity).getSystemWindowInsetTop() == expected);
+ waitForTopInsetEqual(activity, expected);
assertEquals(expected, getInsets(activity).getSystemWindowInsetTop());
}
+ private void waitForTopInsetEqual(Activity activity, int expected) {
+ waitFor(() -> getInsets(activity).getSystemWindowInsetTop() == expected);
+ }
+
/**
* Asserts the inset at {@param side} of {@param activity} is equal to {@param expected}
* waiting as needed.
*/
private void assertInsetGreaterOrEqual(Activity activity, int side, int expected)
throws Exception {
+ waitForInsetGreaterOrEqual(activity, side, expected);
+
+ final WindowInsets insets = getInsets(activity);
+ switch (side) {
+ case TOP: assertGreaterOrEqual(insets.getSystemWindowInsetTop(), expected); break;
+ case BOTTOM: assertGreaterOrEqual(insets.getSystemWindowInsetBottom(), expected); break;
+ case LEFT: assertGreaterOrEqual(insets.getSystemWindowInsetLeft(), expected); break;
+ case RIGHT: assertGreaterOrEqual(insets.getSystemWindowInsetRight(), expected); break;
+ }
+ }
+
+ private void waitForInsetGreaterOrEqual(Activity activity, int side, int expected) {
waitFor(() -> {
final WindowInsets insets = getInsets(activity);
switch (side) {
@@ -275,14 +291,6 @@
default: return true;
}
});
-
- final WindowInsets insets = getInsets(activity);
- switch (side) {
- case TOP: assertGreaterOrEqual(insets.getSystemWindowInsetTop(), expected); break;
- case BOTTOM: assertGreaterOrEqual(insets.getSystemWindowInsetBottom(), expected); break;
- case LEFT: assertGreaterOrEqual(insets.getSystemWindowInsetLeft(), expected); break;
- case RIGHT: assertGreaterOrEqual(insets.getSystemWindowInsetRight(), expected); break;
- }
}
/** Asserts that the first entry is greater than or equal to the second entry. */
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index ee028ba..735e284 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -19,6 +19,7 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import android.annotation.Nullable;
@@ -30,7 +31,6 @@
import android.os.IBinder;
import android.os.RemoteException;
import android.util.proto.ProtoOutputStream;
-import android.view.Display;
import android.view.DisplayCutout;
import android.view.IWindow;
import android.view.IWindowManager;
@@ -72,14 +72,7 @@
}
- @Override
- public boolean isDefaultOrientationForced() {
- return false;
- }
-
- @Override
- public void setInitialDisplaySize(Display display, int width, int height, int density) {
-
+ public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
}
@Override
@@ -159,9 +152,11 @@
final WindowManagerService wm = mWmSupplier.get();
synchronized (wm.mWindowMap) {
atoken = wm.mRoot.getAppWindowToken(appToken);
+ IWindow iWindow = mock(IWindow.class);
+ doReturn(mock(IBinder.class)).when(iWindow).asBinder();
window = WindowTestsBase.createWindow(null, TYPE_APPLICATION_STARTING, atoken,
"Starting window", 0 /* ownerId */, false /* internalWindows */, wm,
- mock(Session.class), mock(IWindow.class));
+ mock(Session.class), iWindow);
atoken.startingWindow = window;
}
if (mRunnableWhenAddingSplashScreen != null) {
@@ -386,22 +381,6 @@
public void onKeyguardOccludedChangedLw(boolean occluded) {
}
- @Override
- public int rotationForOrientationLw(int orientation, int lastRotation, boolean defaultDisplay) {
- return rotationToReport;
- }
-
- @Override
- public boolean rotationHasCompatibleMetricsLw(int orientation, int rotation) {
- return true;
- }
-
- @Override
- public void setRotationLw(int rotation) {
-
- }
-
- @Override
public void setSafeMode(boolean safeMode) {
}
@@ -437,11 +416,6 @@
}
@Override
- public void setCurrentOrientationLw(int newOrientation) {
-
- }
-
- @Override
public boolean performHapticFeedbackLw(WindowState win, int effectId,
boolean always) {
return false;
@@ -559,12 +533,13 @@
}
@Override
- public void onConfigurationChanged() {
+ public void onConfigurationChanged(DisplayContentInfo displayContentInfo) {
}
@Override
- public boolean shouldRotateSeamlessly(int oldRotation, int newRotation) {
+ public boolean shouldRotateSeamlessly(DisplayRotation displayRotation, int oldRotation,
+ int newRotation) {
return false;
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
index ca520ed..9dc0025 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowAnimationSpecTest.java
@@ -70,8 +70,6 @@
true /* isAppAnimation */);
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty));
- verify(mTransaction).setFinalCrop(eq(mSurfaceControl),
- argThat(rect -> rect.equals(mStackBounds)));
}
@Test
@@ -83,9 +81,6 @@
true /* isAppAnimation */);
windowAnimationSpec.apply(mTransaction, mSurfaceControl, 0);
verify(mTransaction).setWindowCrop(eq(mSurfaceControl), argThat(Rect::isEmpty));
- verify(mTransaction).setFinalCrop(eq(mSurfaceControl),
- argThat(rect -> rect.left == 20 && rect.top == 40 && rect.right == 30
- && rect.bottom == 50));
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 4864332..431d1a7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -121,13 +121,52 @@
mStubStack = new TaskStack(sWm, 0, null);
}
- public void assertRect(Rect rect, int left, int top, int right, int bottom) {
+ // Do not use this function directly in the tests below. Instead, use more explicit function
+ // such as assertFlame().
+ private void assertRect(Rect rect, int left, int top, int right, int bottom) {
assertEquals(left, rect.left);
assertEquals(top, rect.top);
assertEquals(right, rect.right);
assertEquals(bottom, rect.bottom);
}
+ private void assertContentInset(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.mContentInsets, left, top, right, bottom);
+ }
+
+ private void assertVisibleInset(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.mVisibleInsets, left, top, right, bottom);
+ }
+
+ private void assertStableInset(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.mStableInsets, left, top, right, bottom);
+ }
+
+ private void assertFrame(WindowState w, int left, int top, int right, int bottom) {
+ assertRect(w.getFrameLw(), left, top, right, bottom);
+ }
+
+ private void assertContentFrame(WindowState w, Rect expectedRect) {
+ assertRect(w.getContentFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ expectedRect.bottom);
+ }
+
+ private void assertVisibleFrame(WindowState w, Rect expectedRect) {
+ assertRect(w.getVisibleFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ expectedRect.bottom);
+ }
+
+ private void assertStableFrame(WindowState w, Rect expectedRect) {
+ assertRect(w.getStableFrameLw(), expectedRect.left, expectedRect.top, expectedRect.right,
+ expectedRect.bottom);
+ }
+
+ private void assertPolicyCrop(WindowStateWithTask w, int left, int top, int right, int bottom) {
+ Rect policyCrop = new Rect();
+ w.calculatePolicyCrop(policyCrop);
+ assertRect(policyCrop, left, top, right, bottom);
+ }
+
@Test
public void testLayoutInFullscreenTaskInsets() throws Exception {
Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
@@ -163,14 +202,13 @@
// and stable frames work the same way.
final WindowFrames windowFrames = new WindowFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(),0, 0, 1000, 1000);
- assertRect(w.mContentInsets, 0, topContentInset, 0, bottomContentInset);
- assertRect(w.mVisibleInsets, 0, topVisibleInset, 0, bottomVisibleInset);
- assertRect(w.mStableInsets, leftStableInset, 0, rightStableInset, 0);
- // The frames remain as passed in shrunk to the window frame
- assertTrue(cf.equals(w.getContentFrameLw()));
- assertTrue(vf.equals(w.getVisibleFrameLw()));
- assertTrue(sf.equals(w.getStableFrameLw()));
+ assertFrame(w, 0, 0, 1000, 1000);
+ assertContentInset(w, 0, topContentInset, 0, bottomContentInset);
+ assertVisibleInset(w, 0, topVisibleInset, 0, bottomVisibleInset);
+ assertStableInset(w, leftStableInset, 0, rightStableInset, 0);
+ assertContentFrame(w, cf);
+ assertVisibleFrame(w, vf);
+ assertStableFrame(w, sf);
// On the other hand getFrame() doesn't extend past cf we won't get any insets
w.mAttrs.x = 100;
w.mAttrs.y = 100;
@@ -178,12 +216,12 @@
w.mRequestedWidth = 100;
w.mRequestedHeight = 100;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 100, 100, 200, 200);
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, 100, 100, 200, 200);
+ assertContentInset(w, 0, 0, 0, 0);
// In this case the frames are shrunk to the window frame.
- assertTrue(w.getFrameLw().equals(w.getContentFrameLw()));
- assertTrue(w.getFrameLw().equals(w.getVisibleFrameLw()));
- assertTrue(w.getFrameLw().equals(w.getStableFrameLw()));
+ assertContentFrame(w, w.getFrameLw());
+ assertVisibleFrame(w, w.getFrameLw());
+ assertStableFrame(w, w.getFrameLw());
}
@Test
@@ -200,7 +238,7 @@
// so we expect it to fill the entire available frame.
final WindowFrames windowFrames = new WindowFrames(pf, pf, pf, pf, pf, pf, pf, pf);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 1000, 1000);
+ assertFrame(w, 0, 0, 1000, 1000);
// It can select various widths and heights within the bounds.
// Strangely the window attribute width is ignored for normal windows
@@ -210,14 +248,14 @@
w.computeFrameLw(windowFrames);
// Explicit width and height without requested width/height
// gets us nothing.
- assertRect(w.getFrameLw(), 0, 0, 0, 0);
+ assertFrame(w, 0, 0, 0, 0);
w.mRequestedWidth = 300;
w.mRequestedHeight = 300;
w.computeFrameLw(windowFrames);
// With requestedWidth/Height we can freely choose our size within the
// parent bounds.
- assertRect(w.getFrameLw(), 0, 0, 300, 300);
+ assertFrame(w, 0, 0, 300, 300);
// With FLAG_SCALED though, requestedWidth/height is used to control
// the unscaled surface size, and mAttrs.width/height becomes the
@@ -228,14 +266,14 @@
w.mAttrs.width = 100;
w.mAttrs.height = 100;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 100, 100);
+ assertFrame(w, 0, 0, 100, 100);
w.mAttrs.flags = 0;
// But sizes too large will be clipped to the containing frame
w.mRequestedWidth = 1200;
w.mRequestedHeight = 1200;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 1000, 1000);
+ assertFrame(w, 0, 0, 1000, 1000);
// Before they are clipped though windows will be shifted
w.mAttrs.x = 300;
@@ -243,7 +281,7 @@
w.mRequestedWidth = 1000;
w.mRequestedHeight = 1000;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 0, 0, 1000, 1000);
+ assertFrame(w, 0, 0, 1000, 1000);
// If there is room to move around in the parent frame the window will be shifted according
// to gravity.
@@ -253,16 +291,16 @@
w.mRequestedHeight = 300;
w.mAttrs.gravity = Gravity.RIGHT | Gravity.TOP;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 700, 0, 1000, 300);
+ assertFrame(w, 700, 0, 1000, 300);
w.mAttrs.gravity = Gravity.RIGHT | Gravity.BOTTOM;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 700, 700, 1000, 1000);
+ assertFrame(w, 700, 700, 1000, 1000);
// Window specified x and y are interpreted as offsets in the opposite
// direction of gravity
w.mAttrs.x = 100;
w.mAttrs.y = 100;
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), 600, 600, 900, 900);
+ assertFrame(w, 600, 600, 900, 900);
}
@Test
@@ -286,24 +324,23 @@
w.computeFrameLw(windowFrames);
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
+ assertContentFrame(w, taskBounds);
+ assertContentInset(w, 0, 0, 0, 0);
pf.set(0, 0, logicalWidth, logicalHeight);
// We still produce insets against the containing frame the same way.
final int cfRight = logicalWidth / 2;
final int cfBottom = logicalHeight / 2;
final Rect cf = new Rect(0, 0, cfRight, cfBottom);
-
windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
int contentInsetRight = taskRight - cfRight;
int contentInsetBottom = taskBottom - cfBottom;
- assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
- taskBottom - contentInsetBottom);
+ assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
+ assertContentFrame(w, new Rect(taskLeft, taskTop, taskRight - contentInsetRight,
+ taskBottom - contentInsetBottom));
pf.set(0, 0, logicalWidth, logicalHeight);
// However if we set temp inset bounds, the insets will be computed
@@ -314,15 +351,14 @@
final int insetRight = insetLeft + (taskRight - taskLeft);
final int insetBottom = insetTop + (taskBottom - taskTop);
task.mInsetBounds.set(insetLeft, insetTop, insetRight, insetBottom);
-
windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
contentInsetRight = insetRight - cfRight;
contentInsetBottom = insetBottom - cfBottom;
- assertRect(w.mContentInsets, 0, 0, contentInsetRight, contentInsetBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight - contentInsetRight,
- taskBottom - contentInsetBottom);
+ assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom);
+ assertContentFrame(w, new Rect(taskLeft, taskTop, taskRight - contentInsetRight,
+ taskBottom - contentInsetBottom));
}
@Test
@@ -344,20 +380,16 @@
final Rect vf = cf;
final Rect sf = vf;
// We use a decor content frame with insets to produce cropping.
- Rect dcf = cf;
-
- final Rect policyCrop = new Rect();
+ Rect dcf = new Rect(cf);
final WindowFrames windowFrames = new WindowFrames(pf, df, of, cf, vf, dcf, sf, mEmptyRect);
w.computeFrameLw(windowFrames);
- w.calculatePolicyCrop(policyCrop);
- assertRect(policyCrop, 0, cf.top, logicalWidth, cf.bottom);
+ assertPolicyCrop(w, 0, cf.top, logicalWidth, cf.bottom);
windowFrames.mDecorFrame.setEmpty();
// Likewise with no decor frame we would get no crop
w.computeFrameLw(windowFrames);
- w.calculatePolicyCrop(policyCrop);
- assertRect(policyCrop, 0, 0, logicalWidth, logicalHeight);
+ assertPolicyCrop(w, 0, 0, logicalWidth, logicalHeight);
// Now we set up a window which doesn't fill the entire decor frame.
// Normally it would be cropped to it's frame but in the case of docked resizing
@@ -372,16 +404,14 @@
w.mRequestedHeight = logicalHeight / 2;
w.computeFrameLw(windowFrames);
- w.calculatePolicyCrop(policyCrop);
// Normally the crop is shrunk from the decor frame
// to the computed window frame.
- assertRect(policyCrop, 0, 0, logicalWidth / 2, logicalHeight / 2);
+ assertPolicyCrop(w, 0, 0, logicalWidth / 2, logicalHeight / 2);
w.mDockedResizingForTest = true;
- w.calculatePolicyCrop(policyCrop);
// But if we are docked resizing it won't be, however we will still be
// shrunk to the decor frame and the display.
- assertRect(policyCrop, 0, 0,
+ assertPolicyCrop(w, 0, 0,
Math.min(pf.width(), displayInfo.logicalWidth),
Math.min(pf.height(), displayInfo.logicalHeight));
}
@@ -409,9 +439,9 @@
w.computeFrameLw(windowFrames);
// For non fullscreen tasks the containing frame is based off the
// task bounds not the parent frame.
- assertRect(w.getFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.getContentFrameLw(), taskLeft, taskTop, taskRight, taskBottom);
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, taskLeft, taskTop, taskRight, taskBottom);
+ assertContentFrame(w, taskBounds);
+ assertContentInset(w, 0, 0, 0, 0);
// Now simulate switch to fullscreen for letterboxed app.
final int xInset = logicalWidth / 10;
@@ -422,12 +452,11 @@
w.mAppToken.onOverrideConfigurationChanged(config);
pf.set(0, 0, logicalWidth, logicalHeight);
task.mFullscreenForTest = true;
-
windowFrames.setFrames(pf, pf, pf, cf, cf, pf, cf, mEmptyRect);
w.computeFrameLw(windowFrames);
- assertEquals(cf, w.getFrameLw());
- assertEquals(cf, w.getContentFrameLw());
- assertRect(w.mContentInsets, 0, 0, 0, 0);
+ assertFrame(w, cf.left, cf.top, cf.right, cf.bottom);
+ assertContentFrame(w, cf);
+ assertContentInset(w, 0, 0, 0, 0);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index 2e4740b..a1b1640 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -22,8 +22,12 @@
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
+import android.view.Display;
import android.view.IApplicationToken;
import android.view.IWindow;
+import android.view.Surface;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;
import static android.app.AppOpsManager.OP_NONE;
@@ -58,6 +62,37 @@
return service;
}
+ /** An extension of {@link DisplayContent} to gain package scoped access. */
+ public static class TestDisplayContent extends DisplayContent {
+
+ private TestDisplayContent(Display display, WindowManagerService service,
+ WallpaperController wallpaperController, DisplayWindowController controller) {
+ super(display, service, wallpaperController, controller);
+ }
+
+ /** Create a mocked default {@link DisplayContent}. */
+ public static TestDisplayContent create(Context context) {
+ final TestDisplayContent displayContent = mock(TestDisplayContent.class);
+ displayContent.isDefaultDisplay = true;
+
+ final DisplayPolicy displayPolicy = mock(DisplayPolicy.class);
+ when(displayPolicy.navigationBarCanMove()).thenReturn(true);
+ when(displayPolicy.hasNavigationBar()).thenReturn(true);
+
+ final DisplayRotation displayRotation = new DisplayRotation(
+ mock(WindowManagerService.class), displayContent, displayPolicy,
+ context, new Object());
+ displayRotation.mPortraitRotation = Surface.ROTATION_0;
+ displayRotation.mLandscapeRotation = Surface.ROTATION_90;
+ displayRotation.mUpsideDownRotation = Surface.ROTATION_180;
+ displayRotation.mSeascapeRotation = Surface.ROTATION_270;
+
+ when(displayContent.getDisplayRotation()).thenReturn(displayRotation);
+
+ return displayContent;
+ }
+ }
+
/**
* Creates a mock instance of {@link StackWindowController}.
*/
@@ -113,6 +148,7 @@
/** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
public static class TestAppWindowToken extends AppWindowToken {
boolean mOnTop = false;
+ private Transaction mPendingTransactionOverride;
private TestAppWindowToken(DisplayContent dc) {
super(dc.mService, new IApplicationToken.Stub() {
@@ -158,6 +194,17 @@
boolean isOnTop() {
return mOnTop;
}
+
+ void setPendingTransaction(Transaction transaction) {
+ mPendingTransactionOverride = transaction;
+ }
+
+ @Override
+ public Transaction getPendingTransaction() {
+ return mPendingTransactionOverride == null
+ ? super.getPendingTransaction()
+ : mPendingTransactionOverride;
+ }
}
static TestWindowToken createTestWindowToken(int type, DisplayContent dc) {
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 473a287..ef019fe 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -231,6 +231,11 @@
}
AppWindowToken createAppWindowToken(DisplayContent dc, int windowingMode, int activityType) {
+ return createTestAppWindowToken(dc, windowingMode, activityType);
+ }
+
+ WindowTestUtils.TestAppWindowToken createTestAppWindowToken(DisplayContent dc, int
+ windowingMode, int activityType) {
final TaskStack stack = createStackControllerOnStackOnDisplay(windowingMode, activityType,
dc).mContainer;
final Task task = createTaskInStack(stack, 0 /* userId */);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index d0a656c..95d4a15 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -25,6 +25,7 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -474,6 +475,59 @@
}
@Test
+ public void testIsPackageAllowed() {
+ for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
+ ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
+ mIpm, approvalLevel);
+ writeExpectedValuesToSettings(approvalLevel);
+ service.migrateToXml();
+
+ verifyExpectedApprovedPackages(service);
+ }
+ }
+
+ @Test
+ public void testUpgradeAppBindsNewServices() throws Exception {
+ // If the primary and secondary lists contain component names, only those components within
+ // the package should be matched
+ ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
+ mIpm,
+ ManagedServices.APPROVAL_BY_PACKAGE);
+
+ List<String> packages = new ArrayList<>();
+ packages.add("package");
+ addExpectedServices(service, packages, 0);
+
+ // only 2 components are approved per package
+ mExpectedPrimaryComponentNames.clear();
+ mExpectedPrimaryPackages.clear();
+ mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2");
+ mExpectedSecondaryComponentNames.clear();
+ mExpectedSecondaryPackages.clear();
+
+ loadXml(service);
+
+ // new component expected
+ mExpectedPrimaryComponentNames.put(0, "package/C1:package/C2:package/C3");
+
+ service.onPackagesChanged(false, new String[]{"package"}, new int[]{0});
+
+ // verify the 3 components per package are enabled (bound)
+ verifyExpectedBoundEntries(service, true);
+
+ // verify the last component per package is not enabled/we don't try to bind to it
+ for (String pkg : packages) {
+ ComponentName unapprovedAdditionalComponent =
+ ComponentName.unflattenFromString(pkg + "/C3");
+ assertFalse(
+ service.isComponentEnabledForCurrentProfiles(
+ unapprovedAdditionalComponent));
+ verify(mIpm, never()).getServiceInfo(
+ eq(unapprovedAdditionalComponent), anyInt(), anyInt());
+ }
+ }
+
+ @Test
public void testSetPackageOrComponentEnabled() throws Exception {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
@@ -640,6 +694,20 @@
}
}
+ @Test
+ public void testIsSameUser() {
+ IInterface service = mock(IInterface.class);
+ when(service.asBinder()).thenReturn(mock(IBinder.class));
+ ManagedServices services = new TestManagedServices(getContext(), mLock, mUserProfiles,
+ mIpm, APPROVAL_BY_PACKAGE);
+ services.registerService(service, null, 10);
+ ManagedServices.ManagedServiceInfo info = services.checkServiceTokenLocked(service);
+ info.isSystem = true;
+
+ assertFalse(services.isSameUser(service, 0));
+ assertTrue(services.isSameUser(service, 10));
+ }
+
private void loadXml(ManagedServices service) throws Exception {
final StringBuffer xml = new StringBuffer();
xml.append("<" + service.getConfig().xmlTag + ">\n");
@@ -729,7 +797,7 @@
if (service.mApprovalLevel == APPROVAL_BY_PACKAGE) {
assertTrue(packageOrComponent,
service.isComponentEnabledForPackage(packageOrComponent));
- for (int i = 1; i <= 3; i ++) {
+ for (int i = 1; i <= 3; i++) {
ComponentName componentName = ComponentName.unflattenFromString(
packageOrComponent +"/C" + i);
assertTrue(service.isComponentEnabledForCurrentProfiles(
@@ -774,6 +842,39 @@
}
}
+
+ private void verifyExpectedApprovedPackages(ManagedServices service) {
+ verifyExpectedApprovedPackages(service, true);
+ verifyExpectedApprovedPackages(service, false);
+ }
+
+ private void verifyExpectedApprovedPackages(ManagedServices service, boolean primary) {
+ ArrayMap<Integer, String> verifyMap = primary
+ ? mExpectedPrimary.get(service.mApprovalLevel)
+ : mExpectedSecondary.get(service.mApprovalLevel);
+ verifyExpectedApprovedPackages(service, verifyMap);
+ }
+
+ private void verifyExpectedApprovedPackages(ManagedServices service,
+ ArrayMap<Integer, String> verifyMap) {
+ for (int userId : verifyMap.keySet()) {
+ for (String verifyValue : verifyMap.get(userId).split(":")) {
+ if (!TextUtils.isEmpty(verifyValue)) {
+ ComponentName component = ComponentName.unflattenFromString(verifyValue);
+ if (component != null ) {
+ assertTrue("service type " + service.mApprovalLevel + ":"
+ + verifyValue + " is not allowed for user " + userId,
+ service.isPackageAllowed(component.getPackageName(), userId));
+ } else {
+ assertTrue("service type " + service.mApprovalLevel + ":"
+ + verifyValue + " is not allowed for user " + userId,
+ service.isPackageAllowed(verifyValue, userId));
+ }
+ }
+ }
+ }
+ }
+
private void writeExpectedValuesToSettings(int approvalLevel) {
for (int userId : mExpectedPrimary.get(approvalLevel).keySet()) {
Settings.Secure.putStringForUser(getContext().getContentResolver(), SETTING,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 742ad65..f255d49 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -95,6 +95,7 @@
assertEquals(getUserSentiment(i), ranking.getUserSentiment());
assertEquals(getHidden(i), ranking.isSuspended());
assertActionsEqual(getSmartActions(key, i), ranking.getSmartActions());
+ assertEquals(getSmartReplies(key, i), ranking.getSmartReplies());
}
}
@@ -112,6 +113,7 @@
Bundle userSentiment = new Bundle();
Bundle mHidden = new Bundle();
Bundle smartActions = new Bundle();
+ Bundle smartReplies = new Bundle();
for (int i = 0; i < mKeys.length; i++) {
String key = mKeys[i];
@@ -130,12 +132,13 @@
userSentiment.putInt(key, getUserSentiment(i));
mHidden.putBoolean(key, getHidden(i));
smartActions.putParcelableArrayList(key, getSmartActions(key, i));
+ smartReplies.putCharSequenceArrayList(key, getSmartReplies(key, i));
}
NotificationRankingUpdate update = new NotificationRankingUpdate(mKeys,
interceptedKeys.toArray(new String[0]), visibilityOverrides,
suppressedVisualEffects, importance, explanation, overrideGroupKeys,
channels, overridePeople, snoozeCriteria, showBadge, userSentiment, mHidden,
- smartActions);
+ smartActions, smartReplies);
return update;
}
@@ -216,6 +219,14 @@
return actions;
}
+ private ArrayList<CharSequence> getSmartReplies(String key, int index) {
+ ArrayList<CharSequence> choices = new ArrayList<>();
+ for (int i = 0; i < index; i++) {
+ choices.add("choice_" + key + "_" + i);
+ }
+ return choices;
+ }
+
private void assertActionsEqual(
List<Notification.Action> expecteds, List<Notification.Action> actuals) {
assertEquals(expecteds.size(), actuals.size());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index a0d145d..0cbb1aa 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -36,6 +36,10 @@
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.os.Build.VERSION_CODES.O_MR1;
import static android.os.Build.VERSION_CODES.P;
+import static android.service.notification.NotificationListenerService.Ranking
+ .USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking
+ .USER_SENTIMENT_NEUTRAL;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -50,7 +54,6 @@
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -84,7 +87,6 @@
import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.graphics.Color;
-import android.media.AudioAttributes;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Binder;
@@ -97,7 +99,6 @@
import android.provider.MediaStore;
import android.provider.Settings.Secure;
import android.service.notification.Adjustment;
-import android.service.notification.INotificationListener;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
import android.service.notification.NotifyingApp;
@@ -110,6 +111,7 @@
import android.text.Html;
import android.util.ArrayMap;
import android.util.AtomicFile;
+import android.util.Log;
import com.android.internal.R;
import com.android.internal.statusbar.NotificationVisibility;
@@ -198,6 +200,7 @@
// Use a Testable subclass so we can simulate calls from the system without failing.
private static class TestableNotificationManagerService extends NotificationManagerService {
int countSystemChecks = 0;
+ boolean isSystemUid = true;
public TestableNotificationManagerService(Context context) {
super(context);
@@ -206,13 +209,13 @@
@Override
protected boolean isCallingUidSystem() {
countSystemChecks++;
- return true;
+ return isSystemUid;
}
@Override
protected boolean isCallerSystemOrPhone() {
countSystemChecks++;
- return true;
+ return isSystemUid;
}
@Override
@@ -650,6 +653,79 @@
assertNull(mService.getNotificationRecord(sbn.getKey()));
}
+ /**
+ * Confirm the system user on automotive devices can use car categories
+ */
+ @Test
+ public void testEnqueuedRestrictedNotifications_asSystem() throws Exception {
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(true);
+ List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
+ Notification.CATEGORY_CAR_WARNING,
+ Notification.CATEGORY_CAR_INFORMATION);
+ int id = 0;
+ for (String category: categories) {
+ final StatusBarNotification sbn =
+ generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
+ sbn.getNotification().category = category;
+ mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+ sbn.getId(), sbn.getNotification(), sbn.getUserId());
+ }
+ waitForIdle();
+ assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
+ }
+
+
+ /**
+ * Confirm restricted notification categories only apply to automotive.
+ */
+ @Test
+ public void testEnqueuedRestrictedNotifications_notAutomotive() throws Exception {
+ mService.isSystemUid = false;
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(false);
+ List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
+ Notification.CATEGORY_CAR_WARNING,
+ Notification.CATEGORY_CAR_INFORMATION);
+ int id = 0;
+ for (String category: categories) {
+ final StatusBarNotification sbn =
+ generateNotificationRecord(mTestNotificationChannel, ++id, "", false).sbn;
+ sbn.getNotification().category = category;
+ mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+ sbn.getId(), sbn.getNotification(), sbn.getUserId());
+ }
+ waitForIdle();
+ assertEquals(categories.size(), mBinderService.getActiveNotifications(PKG).length);
+ }
+
+ /**
+ * Confirm if a non-system user tries to use the car categories on a automotive device that
+ * they will get a security exception
+ */
+ @Test
+ public void testEnqueuedRestrictedNotifications_badUser() throws Exception {
+ mService.isSystemUid = false;
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE, 0))
+ .thenReturn(true);
+ List<String> categories = Arrays.asList(Notification.CATEGORY_CAR_EMERGENCY,
+ Notification.CATEGORY_CAR_WARNING,
+ Notification.CATEGORY_CAR_INFORMATION);
+ for (String category: categories) {
+ final StatusBarNotification sbn = generateNotificationRecord(null).sbn;
+ sbn.getNotification().category = category;
+ try {
+ mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+ sbn.getId(), sbn.getNotification(), sbn.getUserId());
+ fail("Calls from non system apps should not allow use of restricted categories");
+ } catch (SecurityException e) {
+ // pass
+ }
+ }
+ waitForIdle();
+ assertEquals(0, mBinderService.getActiveNotifications(PKG).length);
+ }
+
@Test
public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", 0,
@@ -2396,16 +2472,81 @@
}
@Test
- public void testUserSentimentChangeTriggersUpdate() throws Exception {
+ public void testApplyAdjustmentMultiUser() throws Exception {
final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
mService.addNotification(r);
NotificationManagerService.WorkerHandler handler = mock(
NotificationManagerService.WorkerHandler.class);
mService.setHandler(handler);
+ when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(false);
+
Bundle signals = new Bundle();
signals.putInt(Adjustment.KEY_USER_SENTIMENT,
- NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+ USER_SENTIMENT_NEGATIVE);
+ Adjustment adjustment = new Adjustment(
+ r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+ mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+
+ waitForIdle();
+
+ verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
+ }
+
+ @Test
+ public void testApplyEnqueuedAdjustmentFromAssistant_singleUser() throws Exception {
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.WorkerHandler handler = mock(
+ NotificationManagerService.WorkerHandler.class);
+ mService.setHandler(handler);
+ when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT,
+ USER_SENTIMENT_NEGATIVE);
+ Adjustment adjustment = new Adjustment(
+ r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
+
+ assertEquals(USER_SENTIMENT_NEGATIVE, r.getUserSentiment());
+ }
+
+ @Test
+ public void testApplyEnqueuedAdjustmentFromAssistant_crossUser() throws Exception {
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.WorkerHandler handler = mock(
+ NotificationManagerService.WorkerHandler.class);
+ mService.setHandler(handler);
+ when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(false);
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT,
+ USER_SENTIMENT_NEGATIVE);
+ Adjustment adjustment = new Adjustment(
+ r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
+ mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
+
+ assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment());
+
+ waitForIdle();
+
+ verify(handler, timeout(300).times(0)).scheduleSendRankingUpdate();
+ }
+
+ @Test
+ public void testUserSentimentChangeTriggersUpdate() throws Exception {
+ final NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+ mService.addNotification(r);
+ NotificationManagerService.WorkerHandler handler = mock(
+ NotificationManagerService.WorkerHandler.class);
+ mService.setHandler(handler);
+ when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
+
+ Bundle signals = new Bundle();
+ signals.putInt(Adjustment.KEY_USER_SENTIMENT,
+ USER_SENTIMENT_NEGATIVE);
Adjustment adjustment = new Adjustment(
r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
mBinderService.applyAdjustmentFromAssistant(null, adjustment);
@@ -2422,10 +2563,11 @@
NotificationManagerService.WorkerHandler handler = mock(
NotificationManagerService.WorkerHandler.class);
mService.setHandler(handler);
+ when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Bundle signals = new Bundle();
signals.putInt(Adjustment.KEY_USER_SENTIMENT,
- NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+ USER_SENTIMENT_NEGATIVE);
Adjustment adjustment = new Adjustment(
r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
@@ -2442,15 +2584,16 @@
NotificationManagerService.WorkerHandler handler = mock(
NotificationManagerService.WorkerHandler.class);
mService.setHandler(handler);
+ when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
Bundle signals = new Bundle();
signals.putInt(Adjustment.KEY_USER_SENTIMENT,
- NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+ USER_SENTIMENT_NEGATIVE);
Adjustment adjustment = new Adjustment(
r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
- assertEquals(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE,
+ assertEquals(USER_SENTIMENT_NEGATIVE,
r.getUserSentiment());
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 2a22600..24beb59 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -618,7 +618,7 @@
public void testReadXml() throws Exception {
setupZenConfig();
- // automatic zen rule is enabled on upgrade so rules should not be overriden by default
+ // automatic zen rule is enabled on upgrade so rules should not be overriden to default
ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
final ScheduleInfo weeknights = new ScheduleInfo();
@@ -756,7 +756,8 @@
public void testReadXmlResetDefaultRules() throws Exception {
setupZenConfig();
- // no enabled automatic zen rule, so rules should be overriden by default rules
+ // no enabled automatic zen rules and no default rules
+ // so rules should be overriden by default rules
mZenModeHelperSpy.mConfig.automaticRules = new ArrayMap<>();
// set previous version
@@ -782,8 +783,8 @@
public void testReadXmlAllDisabledRulesResetDefaultRules() throws Exception {
setupZenConfig();
- // all automatic zen rules are diabled on upgrade so rules should be overriden by default
- // rules
+ // all automatic zen rules are diabled on upgrade (and default rules don't already exist)
+ // so rules should be overriden by default rules
ArrayMap<String, ZenModeConfig.ZenRule> enabledAutoRule = new ArrayMap<>();
ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
final ScheduleInfo weeknights = new ScheduleInfo();
@@ -813,6 +814,108 @@
setupZenConfigMaintained();
}
+ @Test
+ public void testReadXmlOnlyOneDefaultRuleExists() throws Exception {
+ setupZenConfig();
+
+ // all automatic zen rules are disabled on upgrade and only one default rule exists
+ // so rules should be overriden to the default rules
+ ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
+ ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
+ final ScheduleInfo customRuleInfo = new ScheduleInfo();
+ customRule.enabled = false;
+ customRule.name = "Custom Rule";
+ customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
+ automaticRules.put("customRule", customRule);
+
+ ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
+ final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo();
+ defaultScheduleRule.enabled = false;
+ defaultScheduleRule.name = "Default Schedule Rule";
+ defaultScheduleRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
+ defaultScheduleRuleInfo);
+ defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
+ automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
+
+ mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+
+ // set previous version
+ ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(
+ new ByteArrayInputStream(baos.toByteArray())), null);
+ parser.nextTag();
+ mZenModeHelperSpy.readXml(parser, false);
+
+ // check default rules
+ ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+ assertTrue(rules.size() != 0);
+ for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
+ assertTrue(rules.containsKey(defaultId));
+ }
+ assertFalse(rules.containsKey("customRule"));
+
+ setupZenConfigMaintained();
+ }
+
+
+ @Test
+ public void testReadXmlDefaultRulesExist() throws Exception {
+ setupZenConfig();
+
+ // Default rules exist so rules should not be overridden by defaults
+ ArrayMap<String, ZenModeConfig.ZenRule> automaticRules = new ArrayMap<>();
+ ZenModeConfig.ZenRule customRule = new ZenModeConfig.ZenRule();
+ final ScheduleInfo customRuleInfo = new ScheduleInfo();
+ customRule.enabled = false;
+ customRule.name = "Custom Rule";
+ customRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ customRule.conditionId = ZenModeConfig.toScheduleConditionId(customRuleInfo);
+ automaticRules.put("customRule", customRule);
+
+ ZenModeConfig.ZenRule defaultScheduleRule = new ZenModeConfig.ZenRule();
+ final ScheduleInfo defaultScheduleRuleInfo = new ScheduleInfo();
+ defaultScheduleRule.enabled = false;
+ defaultScheduleRule.name = "Default Schedule Rule";
+ defaultScheduleRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ defaultScheduleRule.conditionId = ZenModeConfig.toScheduleConditionId(
+ defaultScheduleRuleInfo);
+ defaultScheduleRule.id = ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID;
+ automaticRules.put(ZenModeConfig.EVERY_NIGHT_DEFAULT_RULE_ID, defaultScheduleRule);
+
+ ZenModeConfig.ZenRule defaultEventRule = new ZenModeConfig.ZenRule();
+ final ScheduleInfo defaultEventRuleInfo = new ScheduleInfo();
+ defaultEventRule.enabled = false;
+ defaultEventRule.name = "Default Event Rule";
+ defaultEventRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ defaultEventRule.conditionId = ZenModeConfig.toScheduleConditionId(
+ defaultEventRuleInfo);
+ defaultEventRule.id = ZenModeConfig.EVENTS_DEFAULT_RULE_ID;
+ automaticRules.put(ZenModeConfig.EVENTS_DEFAULT_RULE_ID, defaultEventRule);
+
+ mZenModeHelperSpy.mConfig.automaticRules = automaticRules;
+
+ // set previous version
+ ByteArrayOutputStream baos = writeXmlAndPurge(false, 5);
+ XmlPullParser parser = Xml.newPullParser();
+ parser.setInput(new BufferedInputStream(
+ new ByteArrayInputStream(baos.toByteArray())), null);
+ parser.nextTag();
+ mZenModeHelperSpy.readXml(parser, false);
+
+ // check default rules
+ ArrayMap<String, ZenModeConfig.ZenRule> rules = mZenModeHelperSpy.mConfig.automaticRules;
+ assertTrue(rules.size() != 0);
+ for (String defaultId : ZenModeConfig.DEFAULT_RULE_IDS) {
+ assertTrue(rules.containsKey(defaultId));
+ }
+ assertTrue(rules.containsKey("customRule"));
+
+ setupZenConfigMaintained();
+ }
+
private void setupZenConfig() {
mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
mZenModeHelperSpy.mConfig.allowAlarms = false;
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 22958d4..62fc9c4 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -843,6 +843,7 @@
public void onRemoteRttRequest(Connection c) {}
/** @hide */
public void onPhoneAccountChanged(Connection c, PhoneAccountHandle pHandle) {}
+ public void onConnectionTimeReset(Connection c) {}
}
/**
@@ -2372,6 +2373,16 @@
}
/**
+ * @hide
+ * Resets the cdma connection time.
+ */
+ public final void resetConnectionTime() {
+ for (Listener l : mListeners) {
+ l.onConnectionTimeReset(this);
+ }
+ }
+
+ /**
* Returns the connections or conferences with which this connection can be conferenced.
*/
public final List<Conferenceable> getConferenceables() {
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 2291090..61adcdd 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -1474,6 +1474,13 @@
mAdapter.onPhoneAccountChanged(id, pHandle);
}
}
+
+ public void onConnectionTimeReset(Connection c) {
+ String id = mIdByConnection.get(c);
+ if (id != null) {
+ mAdapter.resetConnectionTime(id);
+ }
+ }
};
/** {@inheritDoc} */
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
index 0d319bb..520e7ed 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java
@@ -255,6 +255,18 @@
}
/**
+ * Resets the cdma connection time.
+ */
+ void resetConnectionTime(String callId) {
+ for (IConnectionServiceAdapter adapter : mAdapters) {
+ try {
+ adapter.resetConnectionTime(callId, Log.getExternalSession());
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ /**
* Indicates that the call no longer exists. Can be used with either a call or a conference
* call.
*
diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
index 3e1bf77..78d65e6 100644
--- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
+++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java
@@ -610,6 +610,11 @@
public void onConnectionServiceFocusReleased(Session.Info sessionInfo) {
mHandler.obtainMessage(MSG_CONNECTION_SERVICE_FOCUS_RELEASED).sendToTarget();
}
+
+ @Override
+ public void resetConnectionTime(String callId, Session.Info sessionInfo) {
+ // Do nothing
+ }
};
public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) {
diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java
index bb4b483..9821dcb 100644
--- a/telecomm/java/android/telecom/RemoteConnectionService.java
+++ b/telecomm/java/android/telecom/RemoteConnectionService.java
@@ -466,6 +466,11 @@
Log.w(this, "onRemoteRttRequest called on a remote conference");
}
}
+
+ @Override
+ public void resetConnectionTime(String callId, Session.Info sessionInfo) {
+ // Do nothing
+ }
};
private final ConnectionServiceAdapterServant mServant =
diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
index be474bd..0157a58 100644
--- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
+++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl
@@ -121,4 +121,6 @@
in Session.Info sessionInfo);
void onConnectionServiceFocusReleased(in Session.Info sessionInfo);
+
+ void resetConnectionTime(String callIdi, in Session.Info sessionInfo);
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 9e23c5c..b2eb5e0 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1553,7 +1553,8 @@
ITelephony telephony = getITelephony();
if (telephony == null)
return null;
- return telephony.getNeighboringCellInfo(mContext.getOpPackageName());
+ return telephony.getNeighboringCellInfo(mContext.getOpPackageName(),
+ mContext.getApplicationInfo().targetSdkVersion);
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
diff --git a/telephony/java/com/android/ims/internal/uce/common/CapInfo.java b/telephony/java/com/android/ims/internal/uce/common/CapInfo.java
index 56969a8..a9847ba 100644
--- a/telephony/java/com/android/ims/internal/uce/common/CapInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/common/CapInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.common;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -73,6 +74,7 @@
/**
* Constructor for the CapInfo class.
*/
+ @UnsupportedAppUsage
public CapInfo() {
};
@@ -80,6 +82,7 @@
/**
* Checks whether IM is supported.
*/
+ @UnsupportedAppUsage
public boolean isImSupported() {
return mImSupported;
}
@@ -87,6 +90,7 @@
/**
* Sets IM as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setImSupported(boolean imSupported) {
this.mImSupported = imSupported;
}
@@ -94,6 +98,7 @@
/**
* Checks whether FT Thumbnail is supported.
*/
+ @UnsupportedAppUsage
public boolean isFtThumbSupported() {
return mFtThumbSupported;
}
@@ -101,6 +106,7 @@
/**
* Sets FT thumbnail as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtThumbSupported(boolean ftThumbSupported) {
this.mFtThumbSupported = ftThumbSupported;
}
@@ -110,6 +116,7 @@
/**
* Checks whether FT Store and Forward is supported
*/
+ @UnsupportedAppUsage
public boolean isFtSnFSupported() {
return mFtSnFSupported;
}
@@ -117,6 +124,7 @@
/**
* Sets FT Store and Forward as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtSnFSupported(boolean ftSnFSupported) {
this.mFtSnFSupported = ftSnFSupported;
}
@@ -124,6 +132,7 @@
/**
* Checks whether File transfer HTTP is supported.
*/
+ @UnsupportedAppUsage
public boolean isFtHttpSupported() {
return mFtHttpSupported;
}
@@ -131,6 +140,7 @@
/**
* Sets File transfer HTTP as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtHttpSupported(boolean ftHttpSupported) {
this.mFtHttpSupported = ftHttpSupported;
}
@@ -138,6 +148,7 @@
/**
* Checks whether FT is supported.
*/
+ @UnsupportedAppUsage
public boolean isFtSupported() {
return mFtSupported;
}
@@ -145,6 +156,7 @@
/**
* Sets FT as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFtSupported(boolean ftSupported) {
this.mFtSupported = ftSupported;
}
@@ -152,6 +164,7 @@
/**
* Checks whether IS is supported.
*/
+ @UnsupportedAppUsage
public boolean isIsSupported() {
return mIsSupported;
}
@@ -159,6 +172,7 @@
/**
* Sets IS as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setIsSupported(boolean isSupported) {
this.mIsSupported = isSupported;
}
@@ -166,6 +180,7 @@
/**
* Checks whether video sharing is supported during a CS call.
*/
+ @UnsupportedAppUsage
public boolean isVsDuringCSSupported() {
return mVsDuringCSSupported;
}
@@ -174,6 +189,7 @@
* Sets video sharing as supported or not supported during a CS
* call.
*/
+ @UnsupportedAppUsage
public void setVsDuringCSSupported(boolean vsDuringCSSupported) {
this.mVsDuringCSSupported = vsDuringCSSupported;
}
@@ -182,6 +198,7 @@
* Checks whether video sharing outside a voice call is
* supported.
*/
+ @UnsupportedAppUsage
public boolean isVsSupported() {
return mVsSupported;
}
@@ -189,6 +206,7 @@
/**
* Sets video sharing as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setVsSupported(boolean vsSupported) {
this.mVsSupported = vsSupported;
}
@@ -196,6 +214,7 @@
/**
* Checks whether social presence is supported.
*/
+ @UnsupportedAppUsage
public boolean isSpSupported() {
return mSpSupported;
}
@@ -203,6 +222,7 @@
/**
* Sets social presence as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setSpSupported(boolean spSupported) {
this.mSpSupported = spSupported;
}
@@ -211,6 +231,7 @@
* Checks whether capability discovery via presence is
* supported.
*/
+ @UnsupportedAppUsage
public boolean isCdViaPresenceSupported() {
return mCdViaPresenceSupported;
}
@@ -219,6 +240,7 @@
* Sets capability discovery via presence as supported or not
* supported.
*/
+ @UnsupportedAppUsage
public void setCdViaPresenceSupported(boolean cdViaPresenceSupported) {
this.mCdViaPresenceSupported = cdViaPresenceSupported;
}
@@ -226,6 +248,7 @@
/**
* Checks whether IP voice call is supported.
*/
+ @UnsupportedAppUsage
public boolean isIpVoiceSupported() {
return mIpVoiceSupported;
}
@@ -233,6 +256,7 @@
/**
* Sets IP voice call as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setIpVoiceSupported(boolean ipVoiceSupported) {
this.mIpVoiceSupported = ipVoiceSupported;
}
@@ -240,6 +264,7 @@
/**
* Checks whether IP video call is supported.
*/
+ @UnsupportedAppUsage
public boolean isIpVideoSupported() {
return mIpVideoSupported;
}
@@ -247,6 +272,7 @@
/**
* Sets IP video call as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setIpVideoSupported(boolean ipVideoSupported) {
this.mIpVideoSupported = ipVideoSupported;
}
@@ -255,6 +281,7 @@
* Checks whether Geo location Pull using File Transfer is
* supported.
*/
+ @UnsupportedAppUsage
public boolean isGeoPullFtSupported() {
return mGeoPullFtSupported;
}
@@ -263,6 +290,7 @@
* Sets Geo location Pull using File Transfer as supported or
* not supported.
*/
+ @UnsupportedAppUsage
public void setGeoPullFtSupported(boolean geoPullFtSupported) {
this.mGeoPullFtSupported = geoPullFtSupported;
}
@@ -270,6 +298,7 @@
/**
* Checks whether Geo Pull is supported.
*/
+ @UnsupportedAppUsage
public boolean isGeoPullSupported() {
return mGeoPullSupported;
}
@@ -277,6 +306,7 @@
/**
* Sets Geo Pull as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setGeoPullSupported(boolean geoPullSupported) {
this.mGeoPullSupported = geoPullSupported;
}
@@ -284,6 +314,7 @@
/**
* Checks whether Geo Push is supported.
*/
+ @UnsupportedAppUsage
public boolean isGeoPushSupported() {
return mGeoPushSupported;
}
@@ -291,6 +322,7 @@
/**
* Sets Geo Push as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setGeoPushSupported(boolean geoPushSupported) {
this.mGeoPushSupported = geoPushSupported;
}
@@ -298,6 +330,7 @@
/**
* Checks whether short messaging is supported.
*/
+ @UnsupportedAppUsage
public boolean isSmSupported() {
return mSmSupported;
}
@@ -305,6 +338,7 @@
/**
* Sets short messaging as supported or not supported.
*/
+ @UnsupportedAppUsage
public void setSmSupported(boolean smSupported) {
this.mSmSupported = smSupported;
}
@@ -312,18 +346,22 @@
/**
* Checks whether store/forward and group chat are supported.
*/
+ @UnsupportedAppUsage
public boolean isFullSnFGroupChatSupported() {
return mFullSnFGroupChatSupported;
}
+ @UnsupportedAppUsage
public boolean isRcsIpVoiceCallSupported() {
return mRcsIpVoiceCallSupported;
}
+ @UnsupportedAppUsage
public boolean isRcsIpVideoCallSupported() {
return mRcsIpVideoCallSupported;
}
+ @UnsupportedAppUsage
public boolean isRcsIpVideoOnlyCallSupported() {
return mRcsIpVideoOnlyCallSupported;
}
@@ -331,16 +369,20 @@
/**
* Sets store/forward and group chat supported or not supported.
*/
+ @UnsupportedAppUsage
public void setFullSnFGroupChatSupported(boolean fullSnFGroupChatSupported) {
this.mFullSnFGroupChatSupported = fullSnFGroupChatSupported;
}
+ @UnsupportedAppUsage
public void setRcsIpVoiceCallSupported(boolean rcsIpVoiceCallSupported) {
this.mRcsIpVoiceCallSupported = rcsIpVoiceCallSupported;
}
+ @UnsupportedAppUsage
public void setRcsIpVideoCallSupported(boolean rcsIpVideoCallSupported) {
this.mRcsIpVideoCallSupported = rcsIpVideoCallSupported;
}
+ @UnsupportedAppUsage
public void setRcsIpVideoOnlyCallSupported(boolean rcsIpVideoOnlyCallSupported) {
this.mRcsIpVideoOnlyCallSupported = rcsIpVideoOnlyCallSupported;
}
@@ -351,17 +393,20 @@
}
/** Sets the list of supported extensions. */
+ @UnsupportedAppUsage
public void setExts(String[] exts) {
this.mExts = exts;
}
/** Gets the time stamp for when to query again. */
+ @UnsupportedAppUsage
public long getCapTimestamp() {
return mCapTimestamp;
}
/** Sets the time stamp for when to query again. */
+ @UnsupportedAppUsage
public void setCapTimestamp(long capTimestamp) {
this.mCapTimestamp = capTimestamp;
}
diff --git a/telephony/java/com/android/ims/internal/uce/common/StatusCode.java b/telephony/java/com/android/ims/internal/uce/common/StatusCode.java
index ad9b669..3921cfb 100644
--- a/telephony/java/com/android/ims/internal/uce/common/StatusCode.java
+++ b/telephony/java/com/android/ims/internal/uce/common/StatusCode.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.common;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -71,12 +72,14 @@
* Constructor for the StatusCode class.
* @hide
*/
+ @UnsupportedAppUsage
public StatusCode() {}
/**
* Gets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public int getStatusCode() {
return mStatusCode;
}
@@ -85,6 +88,7 @@
* Sets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public void setStatusCode(int nStatusCode) {
this.mStatusCode = nStatusCode;
}
diff --git a/telephony/java/com/android/ims/internal/uce/common/UceLong.java b/telephony/java/com/android/ims/internal/uce/common/UceLong.java
index fd07fe8..7207899 100644
--- a/telephony/java/com/android/ims/internal/uce/common/UceLong.java
+++ b/telephony/java/com/android/ims/internal/uce/common/UceLong.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.common;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
@@ -32,6 +33,7 @@
* Constructor for the UceLong class.
* @hide
*/
+ @UnsupportedAppUsage
public UceLong() {
};
@@ -39,6 +41,7 @@
* Gets the long value.
* @hide
*/
+ @UnsupportedAppUsage
public long getUceLong() {
return mUceLong;
}
@@ -47,6 +50,7 @@
* Sets the long value.
* @hide
*/
+ @UnsupportedAppUsage
public void setUceLong(long uceLong) {
this.mUceLong = uceLong;
}
@@ -54,6 +58,7 @@
/** Get the client ID as integer value.
* @hide
*/
+ @UnsupportedAppUsage
public int getClientId() {
return mClientId;
}
@@ -62,6 +67,7 @@
* Set the client ID as integer value.
* @hide
*/
+ @UnsupportedAppUsage
public void setClientId(int nClientId) {
this.mClientId = nClientId;
}
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java b/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java
index c570f49..bcb9f2d 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsCapInfo.java
@@ -15,6 +15,7 @@
*/
package com.android.ims.internal.uce.options;
+import android.annotation.UnsupportedAppUsage;
import com.android.ims.internal.uce.common.CapInfo;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,10 +31,12 @@
return new OptionsCapInfo();
}
+ @UnsupportedAppUsage
public String getSdp() {
return mSdp;
}
+ @UnsupportedAppUsage
public void setSdp(String sdp) {
this.mSdp = sdp;
}
@@ -41,16 +44,19 @@
/**
* Constructor for the OptionsCapInfo class.
*/
+ @UnsupportedAppUsage
public OptionsCapInfo() {
mCapInfo = new CapInfo();
};
+ @UnsupportedAppUsage
public CapInfo getCapInfo() {
return mCapInfo;
}
/**
* Sets the CapInfo
*/
+ @UnsupportedAppUsage
public void setCapInfo(CapInfo capInfo) {
this.mCapInfo = capInfo;
}
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java
index 35f769c..14c64ac 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdId.java
@@ -17,6 +17,7 @@
package com.android.ims.internal.uce.options;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -55,6 +56,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(int nCmdId) {
this.mCmdId = nCmdId;
}
@@ -63,6 +65,7 @@
* Constructor for the OptionsCDCmdId class.
* @hide
*/
+ @UnsupportedAppUsage
public OptionsCmdId(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java
index dab191c..4af3e6e 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java
@@ -19,6 +19,7 @@
import com.android.ims.internal.uce.common.StatusCode;
import com.android.ims.internal.uce.common.CapInfo;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,6 +42,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(OptionsCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -56,6 +58,7 @@
/**
Sets the user data.
@hide */
+ @UnsupportedAppUsage
public void setUserData(int userData) {
this.mUserData = userData;
}
@@ -72,6 +75,7 @@
* Sets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public void setStatus(StatusCode status) {
this.mStatus = status;
}
@@ -80,6 +84,7 @@
* Constructor for the OptionsCmdStatus class.
* @hide
*/
+ @UnsupportedAppUsage
public OptionsCmdStatus() {
mStatus = new StatusCode();
mCapInfo = new CapInfo();
@@ -96,6 +101,7 @@
* Sets the CapInfo
* @hide
*/
+ @UnsupportedAppUsage
public void setCapInfo(CapInfo capInfo) {
this.mCapInfo = capInfo;
}
diff --git a/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java b/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
index 0b9dd21..c5f333d 100644
--- a/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
+++ b/telephony/java/com/android/ims/internal/uce/options/OptionsSipResponse.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.options;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,6 +42,7 @@
* Sets the Options command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(OptionsCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -57,6 +59,7 @@
* Sets the request ID
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -73,6 +76,7 @@
* Sets the SIP response code.
* @hide
*/
+ @UnsupportedAppUsage
public void setSipResponseCode(int sipResponseCode) {
this.mSipResponseCode = sipResponseCode;
}
@@ -89,6 +93,7 @@
* Sets the SIP response code reason phrase.
* @hide
*/
+ @UnsupportedAppUsage
public void setReasonPhrase(String reasonPhrase) {
this.mReasonPhrase = reasonPhrase;
}
@@ -105,6 +110,7 @@
* Sets the SIP retryAfter sec value
* @hide
*/
+ @UnsupportedAppUsage
public void setRetryAfter(int retryAfter) {
this.mRetryAfter = retryAfter;
}
@@ -113,6 +119,7 @@
* Constructor for the OptionsSipResponse class.
* @hide
*/
+ @UnsupportedAppUsage
public OptionsSipResponse() {
mCmdId = new OptionsCmdId();
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java
index 60fc226..745df5b 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresCapInfo.java
@@ -18,6 +18,7 @@
import com.android.ims.internal.uce.common.CapInfo;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -26,12 +27,14 @@
public class PresCapInfo implements Parcelable {
private CapInfo mCapInfo;
+ @UnsupportedAppUsage
private String mContactUri = "";
/**
* Gets the UCE capability information.
* @hide
*/
+ @UnsupportedAppUsage
public CapInfo getCapInfo() {
return mCapInfo;
}
@@ -48,6 +51,7 @@
* Gets the contact URI.
* @hide
*/
+ @UnsupportedAppUsage
public String getContactUri() {
return mContactUri;
}
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java b/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java
index 395f3e8..41020ec 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresCmdId.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -57,6 +58,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(int nCmdId) {
this.mCmdId = nCmdId;
}
@@ -66,6 +68,7 @@
* Constructor for the PresCmdId class.
* @hide
*/
+ @UnsupportedAppUsage
public PresCmdId(){};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java b/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java
index a5b498b..ff8069c 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresCmdStatus.java
@@ -18,6 +18,7 @@
import com.android.ims.internal.uce.common.StatusCode;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -42,6 +43,7 @@
* Sets the command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(PresCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -58,6 +60,7 @@
* Sets the user data.
* @hide
*/
+ @UnsupportedAppUsage
public void setUserData(int userData) {
this.mUserData = userData;
}
@@ -73,6 +76,7 @@
* Sets the status code.
* @hide
*/
+ @UnsupportedAppUsage
public void setStatus(StatusCode status) {
this.mStatus = status;
}
@@ -89,6 +93,7 @@
* Sets the request ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -97,6 +102,7 @@
* Constructor for the PresCmdStatus class.
* @hide
*/
+ @UnsupportedAppUsage
public PresCmdStatus() {
mStatus = new StatusCode();
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java b/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java
index 3e8531a..87193e3 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresPublishTriggerType.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -65,6 +66,7 @@
* Sets the publish trigger type.
* @hide
*/
+ @UnsupportedAppUsage
public void setPublishTrigeerType(int nPublishTriggerType) {
this.mPublishTriggerType = nPublishTriggerType;
}
@@ -74,6 +76,7 @@
* Constructor for the PresPublishTriggerType class.
* @hide
*/
+ @UnsupportedAppUsage
public PresPublishTriggerType(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java
index a073a23..237c999 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresResInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,6 +39,7 @@
* Sets the Presence service resource instance information.
* @hide
*/
+ @UnsupportedAppUsage
public void setInstanceInfo(PresResInstanceInfo instanceInfo) {
this.mInstanceInfo = instanceInfo;
}
@@ -54,6 +56,7 @@
* Sets the resource URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setResUri(String resUri) {
this.mResUri = resUri;
}
@@ -70,6 +73,7 @@
* Sets the display name.
* @hide
*/
+ @UnsupportedAppUsage
public void setDisplayName(String displayName) {
this.mDisplayName = displayName;
}
@@ -79,6 +83,7 @@
* Constructor for the PresResInstanceInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresResInfo() {
mInstanceInfo = new PresResInstanceInfo();
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java
index 430cff1..29699ea 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresResInstanceInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Arrays;
@@ -59,6 +60,7 @@
* Sets the resource instance state.
* @hide
*/
+ @UnsupportedAppUsage
public void setResInstanceState(int nResInstanceState) {
this.mResInstanceState = nResInstanceState;
}
@@ -75,6 +77,7 @@
* Sets the resource ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setResId(String resourceId) {
this.mId = resourceId;
}
@@ -93,6 +96,7 @@
* code.
* @hide
*/
+ @UnsupportedAppUsage
public void setReason(String reason) {
this.mReason = reason;
}
@@ -109,6 +113,7 @@
* Sets the entity URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setPresentityUri(String presentityUri) {
this.mPresentityUri = presentityUri;
}
@@ -125,6 +130,7 @@
* Sets the tuple information.
* @hide
*/
+ @UnsupportedAppUsage
public void setTupleInfo(PresTupleInfo[] tupleInfo) {
this.mTupleInfoArray = new PresTupleInfo[tupleInfo.length];
this.mTupleInfoArray = tupleInfo;
@@ -135,6 +141,7 @@
* Constructor for the PresResInstanceInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresResInstanceInfo(){
};
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java
index 987dd77..ab46e4b 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -60,6 +61,7 @@
* Sets the URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setUri(String uri) {
this.mUri = uri;
}
@@ -76,6 +78,7 @@
* Sets the version.
* @hide
*/
+ @UnsupportedAppUsage
public void setVersion(int version) {
this.mVersion = version;
}
@@ -92,6 +95,7 @@
* Sets the RLMI state.
* @hide
*/
+ @UnsupportedAppUsage
public void setFullState(boolean fullState) {
this.mFullState = fullState;
}
@@ -108,6 +112,7 @@
* Sets the RLMI list name.
* @hide
*/
+ @UnsupportedAppUsage
public void setListName(String listName) {
this.mListName = listName;
}
@@ -124,6 +129,7 @@
* Sets the subscription request ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -140,6 +146,7 @@
* Sets the presence subscription state.
* @hide
*/
+ @UnsupportedAppUsage
public void setPresSubscriptionState(PresSubscriptionState presSubscriptionState) {
this.mPresSubscriptionState = presSubscriptionState;
}
@@ -156,6 +163,7 @@
* Sets the presence subscription expiration time.
* @hide
*/
+ @UnsupportedAppUsage
public void setSubscriptionExpireTime(int subscriptionExpireTime) {
this.mSubscriptionExpireTime = subscriptionExpireTime;
}
@@ -172,6 +180,7 @@
* Sets the presence subscription terminated reason.
* @hide
*/
+ @UnsupportedAppUsage
public void setSubscriptionTerminatedReason(String subscriptionTerminatedReason) {
this.mSubscriptionTerminatedReason = subscriptionTerminatedReason;
}
@@ -180,6 +189,7 @@
* Constructor for the PresTupleInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresRlmiInfo(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java
index f7b7264..83ba722 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresServiceInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -45,6 +46,7 @@
* Gets the media type.
* @hide
*/
+ @UnsupportedAppUsage
public int getMediaType() {
return mMediaCap;
}
@@ -61,6 +63,7 @@
* Gets the service ID.
* @hide
*/
+ @UnsupportedAppUsage
public String getServiceId() {
return mServiceID;
}
@@ -76,6 +79,7 @@
* Gets the service description.
* @hide
*/
+ @UnsupportedAppUsage
public String getServiceDesc() {
return mServiceDesc;
}
@@ -92,6 +96,7 @@
* Gets the service version.
* @hide
*/
+ @UnsupportedAppUsage
public String getServiceVer() {
return mServiceVer;
}
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java b/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java
index 456b443..5e42592 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresSipResponse.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +33,7 @@
* Gets the Presence command ID.
* @hide
*/
+ @UnsupportedAppUsage
public PresCmdId getCmdId() {
return mCmdId;
}
@@ -40,6 +42,7 @@
* Sets the Presence command ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setCmdId(PresCmdId cmdId) {
this.mCmdId = cmdId;
}
@@ -48,6 +51,7 @@
* Gets the request ID.
* @hide
*/
+ @UnsupportedAppUsage
public int getRequestId() {
return mRequestId;
}
@@ -56,6 +60,7 @@
* Sets the request ID.
* @hide
*/
+ @UnsupportedAppUsage
public void setRequestId(int requestId) {
this.mRequestId = requestId;
}
@@ -64,6 +69,7 @@
* Gets the SIP response code.
* @hide
*/
+ @UnsupportedAppUsage
public int getSipResponseCode() {
return mSipResponseCode;
}
@@ -72,6 +78,7 @@
* Sets the SIP response code.
* @hide
*/
+ @UnsupportedAppUsage
public void setSipResponseCode(int sipResponseCode) {
this.mSipResponseCode = sipResponseCode;
}
@@ -82,6 +89,7 @@
* code.
* @hide
*/
+ @UnsupportedAppUsage
public String getReasonPhrase() {
return mReasonPhrase;
}
@@ -90,6 +98,7 @@
* Sets the SIP response code reason phrase.
* @hide
*/
+ @UnsupportedAppUsage
public void setReasonPhrase(String reasonPhrase) {
this.mReasonPhrase = reasonPhrase;
}
@@ -98,6 +107,7 @@
* Gets the SIP retryAfter sec value.
* @hide
*/
+ @UnsupportedAppUsage
public int getRetryAfter() {
return mRetryAfter;
}
@@ -106,6 +116,7 @@
* Sets the SIP retryAfter sec value
* @hide
*/
+ @UnsupportedAppUsage
public void setRetryAfter(int retryAfter) {
this.mRetryAfter = retryAfter;
}
@@ -114,6 +125,7 @@
* Constructor for the PresSipResponse class.
* @hide
*/
+ @UnsupportedAppUsage
public PresSipResponse(){};
/** @hide */
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java b/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java
index 872bc23..bee928c 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresSubscriptionState.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -77,6 +78,7 @@
* Constructor for the PresSubscriptionState class.
* @hide
*/
+ @UnsupportedAppUsage
public PresSubscriptionState() { };
/**
@@ -92,6 +94,7 @@
* Sets the Presence subscription state.
* @hide
*/
+ @UnsupportedAppUsage
public void setPresSubscriptionState(int nPresSubscriptionState) {
this.mPresSubscriptionState = nPresSubscriptionState;
}
diff --git a/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java b/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
index e1867c5..7a47786 100644
--- a/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
+++ b/telephony/java/com/android/ims/internal/uce/presence/PresTupleInfo.java
@@ -16,6 +16,7 @@
package com.android.ims.internal.uce.presence;
+import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -39,6 +40,7 @@
* Sets the feature tag.
* @hide
*/
+ @UnsupportedAppUsage
public void setFeatureTag(String featureTag) {
this.mFeatureTag = featureTag;
}
@@ -54,6 +56,7 @@
* Sets the contact URI.
* @hide
*/
+ @UnsupportedAppUsage
public void setContactUri(String contactUri) {
this.mContactUri = contactUri;
}
@@ -70,6 +73,7 @@
* Sets the timestamp.
* @hide
*/
+ @UnsupportedAppUsage
public void setTimestamp(String timestamp) {
this.mTimestamp = timestamp;
}
@@ -78,6 +82,7 @@
* Constructor for the PresTupleInfo class.
* @hide
*/
+ @UnsupportedAppUsage
public PresTupleInfo(){};
/** @hide */
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d850fbc..f9c3940 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -390,7 +390,7 @@
/**
* Returns the neighboring cell information of the device.
*/
- List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
+ List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg, int targetSdk);
int getCallState();
diff --git a/tests/Internal/res/xml/livewallpaper.xml b/tests/Internal/res/xml/livewallpaper.xml
index dbb0e47..6b5e84e 100644
--- a/tests/Internal/res/xml/livewallpaper.xml
+++ b/tests/Internal/res/xml/livewallpaper.xml
@@ -16,5 +16,4 @@
-->
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
- androidprv:supportsAmbientMode="true"/>
\ No newline at end of file
+ android:supportsAmbientMode="true"/>
\ No newline at end of file
diff --git a/tests/Internal/src/android/app/WallpaperInfoTest.java b/tests/Internal/src/android/app/WallpaperInfoTest.java
index 9d26270..98045ae 100644
--- a/tests/Internal/src/android/app/WallpaperInfoTest.java
+++ b/tests/Internal/src/android/app/WallpaperInfoTest.java
@@ -55,13 +55,13 @@
// Defined as true in the XML
assertTrue("supportsAmbientMode should be true, as defined in the XML.",
- wallpaperInfo.getSupportsAmbientMode());
+ wallpaperInfo.supportsAmbientMode());
Parcel parcel = Parcel.obtain();
wallpaperInfo.writeToParcel(parcel, 0 /* flags */);
parcel.setDataPosition(0);
WallpaperInfo fromParcel = WallpaperInfo.CREATOR.createFromParcel(parcel);
assertTrue("supportsAmbientMode should have been restored from parcelable",
- fromParcel.getSupportsAmbientMode());
+ fromParcel.supportsAmbientMode());
parcel.recycle();
}
}
diff --git a/vr/java/com/google/vr/platform/DeviceInfo.java b/vr/java/com/google/vr/platform/DeviceInfo.java
index f6da66b..6a4617d 100644
--- a/vr/java/com/google/vr/platform/DeviceInfo.java
+++ b/vr/java/com/google/vr/platform/DeviceInfo.java
@@ -1,5 +1,6 @@
package com.google.vr.platform;
+import android.annotation.UnsupportedAppUsage;
import android.os.SystemProperties;
/**
@@ -13,6 +14,7 @@
/**
* Returns true if this device boots directly in VR mode.
*/
+ @UnsupportedAppUsage
public static boolean getVrBoot() {
return SystemProperties.getBoolean(VR_MODE_BOOT, false);
}
diff --git a/vr/java/com/google/vr/platform/Dvr.java b/vr/java/com/google/vr/platform/Dvr.java
index b07d634..41dcd87 100644
--- a/vr/java/com/google/vr/platform/Dvr.java
+++ b/vr/java/com/google/vr/platform/Dvr.java
@@ -1,5 +1,7 @@
package com.google.vr.platform;
+import android.annotation.UnsupportedAppUsage;
+
/**
* Class to load the dvr api.
* @hide
@@ -10,6 +12,7 @@
*
* @return A Long object describing the handle returned by dlopen.
*/
+ @UnsupportedAppUsage
public static Long loadLibrary() {
// Load a thin JNI library that runs dlopen on request.
System.loadLibrary("dvr_loader");
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 43f0e50..f16d006 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -757,9 +757,12 @@
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String BATCHED_SCAN_RESULTS_AVAILABLE_ACTION =
"android.net.wifi.BATCHED_RESULTS";
+
/**
* The RSSI (signal strength) has changed.
- * @see #EXTRA_NEW_RSSI
+ *
+ * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
+ * @see {@link #EXTRA_NEW_RSSI}
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
index 2ea6e79..66297fc 100644
--- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
+++ b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
@@ -16,11 +16,12 @@
package android.net.wifi.hotspot2;
+import android.net.wifi.WifiManager;
import android.os.Handler;
/**
* Base class for provisioning callbacks. Should be extended by applications and set when calling
- * {@link WifiManager#startSubscriptionProvisiong(OsuProvider, ProvisioningCallback, Handler)}.
+ * {@link WifiManager#startSubscriptionProvisioning(OsuProvider, ProvisioningCallback, Handler)}.
*
* @hide
*/
@@ -28,84 +29,101 @@
/**
* The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
*/
- public static final int OSU_FAILURE_AP_CONNECTION = 1;
+ public static final int OSU_FAILURE_AP_CONNECTION = 1;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for invalid server URL address.
*/
public static final int OSU_FAILURE_SERVER_URL_INVALID = 2;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to connection failure to the server.
*/
- public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
+ public static final int OSU_FAILURE_SERVER_CONNECTION = 3;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to invalid server certificate.
*/
- public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
+ public static final int OSU_FAILURE_SERVER_VALIDATION = 4;
/**
- * The reason code for Provisioning Failure due to connection failure to OSU AP.
- * @hide
+ * The reason code for provisioning failure due to invalid service provider.
*/
- public static final int OSU_FAILURE_PROVIDER_VERIFICATION = 5;
+ public static final int OSU_FAILURE_SERVICE_PROVIDER_VERIFICATION = 5;
/**
- * The reason code for Provisioning Failure when a provisioning flow is aborted.
- * @hide
+ * The reason code for provisioning failure when a provisioning flow is aborted.
*/
public static final int OSU_FAILURE_PROVISIONING_ABORTED = 6;
/**
- * The reason code for Provisioning Failure when a provisioning flow is aborted.
- * @hide
+ * The reason code for provisioning failure when a provisioning flow is not possible.
*/
public static final int OSU_FAILURE_PROVISIONING_NOT_AVAILABLE = 7;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The reason code for provisioning failure due to invalid server url.
*/
- public static final int OSU_STATUS_AP_CONNECTING = 1;
+ public static final int OSU_FAILURE_INVALID_SERVER_URL = 8;
/**
- * The status code for Provisioning flow to indicate connected to OSU AP
- * @hide
+ * The reason code for provisioning failure when a command received is not the expected command
+ * type.
*/
- public static final int OSU_STATUS_AP_CONNECTED = 2;
+ public static final int OSU_FAILURE_UNEXPECTED_COMMAND_TYPE = 9;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The reason code for provisioning failure when a SOAP message is not the expected message
+ * type.
*/
- public static final int OSU_STATUS_SERVER_CONNECTED = 3;
+ public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_TYPE = 10;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The reason code for provisioning failure when a SOAP message exchange fails.
*/
- public static final int OSU_STATUS_SERVER_VALIDATED = 4;
+ public static final int OSU_FAILURE_SOAP_MESSAGE_EXCHANGE = 11;
/**
- * The status code for Provisioning flow to indicate connecting to OSU AP
- * @hide
+ * The status code for provisioning flow to indicate connecting to OSU AP
*/
- public static final int OSU_STATUS_PROVIDER_VERIFIED = 5;
+ public static final int OSU_STATUS_AP_CONNECTING = 1;
+
+ /**
+ * The status code for provisioning flow to indicate the OSU AP is connected.
+ */
+ public static final int OSU_STATUS_AP_CONNECTED = 2;
+
+ /**
+ * The status code for provisioning flow to indicate the server connection is completed.
+ */
+ public static final int OSU_STATUS_SERVER_CONNECTED = 3;
+
+ /**
+ * The status code for provisioning flow to indicate the server certificate is validated.
+ */
+ public static final int OSU_STATUS_SERVER_VALIDATED = 4;
+
+ /**
+ * The status code for provisioning flow to indicate the service provider is verified.
+ */
+ public static final int OSU_STATUS_SERVICE_PROVIDER_VERIFIED = 5;
+
+ /**
+ * The status code for provisioning flow to indicate starting the SOAP exchange.
+ */
+ public static final int OSU_STATUS_INIT_SOAP_EXCHANGE = 6;
/**
* Provisioning status for OSU failure
+ *
* @param status indicates error condition
*/
public abstract void onProvisioningFailure(int status);
/**
* Provisioning status when OSU is in progress
+ *
* @param status indicates status of OSU flow
*/
public abstract void onProvisioningStatus(int status);