Merge "Merge "Reduce excess local prefix computations" am: 35d9291ca7 am: 069fd8e996 am: 7b86429051"
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 4bbcfd5..febb922 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -267,10 +267,12 @@
}
}
-LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) {
+LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {}
+
+LogEvent::LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid) {
mLogdTimestampNs = timestampNs;
mTagId = tagId;
- mLogUid = 0;
+ mLogUid = uid;
mContext = create_android_logger(1937006964); // the event tag shared by all stats logs
if (mContext) {
android_log_write_int64(mContext, timestampNs);
@@ -344,7 +346,8 @@
return false;
}
-bool LogEvent::writeKeyValuePairs(const std::map<int32_t, int32_t>& int_map,
+bool LogEvent::writeKeyValuePairs(int32_t uid,
+ const std::map<int32_t, int32_t>& int_map,
const std::map<int32_t, int64_t>& long_map,
const std::map<int32_t, std::string>& string_map,
const std::map<int32_t, float>& float_map) {
@@ -352,6 +355,7 @@
if (android_log_write_list_begin(mContext) < 0) {
return false;
}
+ write(uid);
for (const auto& itr : int_map) {
if (android_log_write_list_begin(mContext) < 0) {
return false;
@@ -561,6 +565,10 @@
}
i++;
} while ((elem.type != EVENT_TYPE_UNKNOWN) && !elem.complete);
+ if (isKeyValuePairAtom && mValues.size() > 0) {
+ mValues[0] = FieldValue(Field(android::util::KEY_VALUE_PAIRS_ATOM, getSimpleField(1)),
+ Value((int32_t)mLogUid));
+ }
}
int64_t LogEvent::GetLong(size_t key, status_t* err) const {
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index c7e2a8c..3d5b2ab 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -75,6 +75,9 @@
// For testing. The timestamp is used as both elapsed real time and logd timestamp.
explicit LogEvent(int32_t tagId, int64_t timestampNs);
+ // For testing. The timestamp is used as both elapsed real time and logd timestamp.
+ explicit LogEvent(int32_t tagId, int64_t timestampNs, int32_t uid);
+
/**
* Constructs a KeyValuePairsAtom LogEvent from value maps.
*/
@@ -147,7 +150,8 @@
bool write(float value);
bool write(const std::vector<AttributionNodeInternal>& nodes);
bool write(const AttributionNodeInternal& node);
- bool writeKeyValuePairs(const std::map<int32_t, int32_t>& int_map,
+ bool writeKeyValuePairs(int32_t uid,
+ const std::map<int32_t, int32_t>& int_map,
const std::map<int32_t, int64_t>& long_map,
const std::map<int32_t, std::string>& string_map,
const std::map<int32_t, float>& float_map);
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index ced65f2..f59ac1a 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -90,7 +90,7 @@
}
TEST(LogEventTest, TestKeyValuePairsAtomParsing) {
- LogEvent event1(83, 2000);
+ LogEvent event1(83, 2000, 1000);
std::map<int32_t, int32_t> int_map;
std::map<int32_t, int64_t> long_map;
std::map<int32_t, std::string> string_map;
@@ -108,7 +108,8 @@
float_map[111] = 2.2f;
float_map[222] = 1.1f;
- EXPECT_TRUE(event1.writeKeyValuePairs(int_map,
+ EXPECT_TRUE(event1.writeKeyValuePairs(0, // Logging side logs 0 uid.
+ int_map,
long_map,
string_map,
float_map));
@@ -116,87 +117,92 @@
EXPECT_EQ(83, event1.GetTagId());
const auto& items = event1.getValues();
- EXPECT_EQ((size_t)16, items.size());
+ EXPECT_EQ((size_t)17, items.size());
const FieldValue& item0 = event1.getValues()[0];
- EXPECT_EQ(0x2010101, item0.mField.getField());
+ EXPECT_EQ(0x10000, item0.mField.getField());
EXPECT_EQ(Type::INT, item0.mValue.getType());
- EXPECT_EQ(11, item0.mValue.int_value);
+ EXPECT_EQ(1000, item0.mValue.int_value);
const FieldValue& item1 = event1.getValues()[1];
- EXPECT_EQ(0x2010182, item1.mField.getField());
+ EXPECT_EQ(0x2010201, item1.mField.getField());
EXPECT_EQ(Type::INT, item1.mValue.getType());
- EXPECT_EQ(123, item1.mValue.int_value);
+ EXPECT_EQ(11, item1.mValue.int_value);
const FieldValue& item2 = event1.getValues()[2];
- EXPECT_EQ(0x2010201, item2.mField.getField());
+ EXPECT_EQ(0x2010282, item2.mField.getField());
EXPECT_EQ(Type::INT, item2.mValue.getType());
- EXPECT_EQ(22, item2.mValue.int_value);
+ EXPECT_EQ(123, item2.mValue.int_value);
const FieldValue& item3 = event1.getValues()[3];
- EXPECT_EQ(0x2010282, item3.mField.getField());
+ EXPECT_EQ(0x2010301, item3.mField.getField());
EXPECT_EQ(Type::INT, item3.mValue.getType());
- EXPECT_EQ(345, item3.mValue.int_value);
+ EXPECT_EQ(22, item3.mValue.int_value);
const FieldValue& item4 = event1.getValues()[4];
- EXPECT_EQ(0x2010301, item4.mField.getField());
+ EXPECT_EQ(0x2010382, item4.mField.getField());
EXPECT_EQ(Type::INT, item4.mValue.getType());
- EXPECT_EQ(33, item4.mValue.int_value);
+ EXPECT_EQ(345, item4.mValue.int_value);
const FieldValue& item5 = event1.getValues()[5];
- EXPECT_EQ(0x2010382, item5.mField.getField());
- EXPECT_EQ(Type::LONG, item5.mValue.getType());
- EXPECT_EQ(678L, item5.mValue.int_value);
+ EXPECT_EQ(0x2010401, item5.mField.getField());
+ EXPECT_EQ(Type::INT, item5.mValue.getType());
+ EXPECT_EQ(33, item5.mValue.int_value);
const FieldValue& item6 = event1.getValues()[6];
- EXPECT_EQ(0x2010401, item6.mField.getField());
- EXPECT_EQ(Type::INT, item6.mValue.getType());
- EXPECT_EQ(44, item6.mValue.int_value);
+ EXPECT_EQ(0x2010482, item6.mField.getField());
+ EXPECT_EQ(Type::LONG, item6.mValue.getType());
+ EXPECT_EQ(678L, item6.mValue.int_value);
const FieldValue& item7 = event1.getValues()[7];
- EXPECT_EQ(0x2010482, item7.mField.getField());
- EXPECT_EQ(Type::LONG, item7.mValue.getType());
- EXPECT_EQ(890L, item7.mValue.int_value);
+ EXPECT_EQ(0x2010501, item7.mField.getField());
+ EXPECT_EQ(Type::INT, item7.mValue.getType());
+ EXPECT_EQ(44, item7.mValue.int_value);
const FieldValue& item8 = event1.getValues()[8];
- EXPECT_EQ(0x2010501, item8.mField.getField());
- EXPECT_EQ(Type::INT, item8.mValue.getType());
- EXPECT_EQ(1, item8.mValue.int_value);
+ EXPECT_EQ(0x2010582, item8.mField.getField());
+ EXPECT_EQ(Type::LONG, item8.mValue.getType());
+ EXPECT_EQ(890L, item8.mValue.int_value);
const FieldValue& item9 = event1.getValues()[9];
- EXPECT_EQ(0x2010583, item9.mField.getField());
- EXPECT_EQ(Type::STRING, item9.mValue.getType());
- EXPECT_EQ("test2", item9.mValue.str_value);
+ EXPECT_EQ(0x2010601, item9.mField.getField());
+ EXPECT_EQ(Type::INT, item9.mValue.getType());
+ EXPECT_EQ(1, item9.mValue.int_value);
const FieldValue& item10 = event1.getValues()[10];
- EXPECT_EQ(0x2010601, item10.mField.getField());
- EXPECT_EQ(Type::INT, item10.mValue.getType());
- EXPECT_EQ(2, item10.mValue.int_value);
+ EXPECT_EQ(0x2010683, item10.mField.getField());
+ EXPECT_EQ(Type::STRING, item10.mValue.getType());
+ EXPECT_EQ("test2", item10.mValue.str_value);
const FieldValue& item11 = event1.getValues()[11];
- EXPECT_EQ(0x2010683, item11.mField.getField());
- EXPECT_EQ(Type::STRING, item11.mValue.getType());
- EXPECT_EQ("test1", item11.mValue.str_value);
+ EXPECT_EQ(0x2010701, item11.mField.getField());
+ EXPECT_EQ(Type::INT, item11.mValue.getType());
+ EXPECT_EQ(2, item11.mValue.int_value);
const FieldValue& item12 = event1.getValues()[12];
- EXPECT_EQ(0x2010701, item12.mField.getField());
- EXPECT_EQ(Type::INT, item12.mValue.getType());
- EXPECT_EQ(111, item12.mValue.int_value);
+ EXPECT_EQ(0x2010783, item12.mField.getField());
+ EXPECT_EQ(Type::STRING, item12.mValue.getType());
+ EXPECT_EQ("test1", item12.mValue.str_value);
const FieldValue& item13 = event1.getValues()[13];
- EXPECT_EQ(0x2010784, item13.mField.getField());
- EXPECT_EQ(Type::FLOAT, item13.mValue.getType());
- EXPECT_EQ(2.2f, item13.mValue.float_value);
+ EXPECT_EQ(0x2010801, item13.mField.getField());
+ EXPECT_EQ(Type::INT, item13.mValue.getType());
+ EXPECT_EQ(111, item13.mValue.int_value);
const FieldValue& item14 = event1.getValues()[14];
- EXPECT_EQ(0x2018801, item14.mField.getField());
- EXPECT_EQ(Type::INT, item14.mValue.getType());
- EXPECT_EQ(222, item14.mValue.int_value);
+ EXPECT_EQ(0x2010884, item14.mField.getField());
+ EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
+ EXPECT_EQ(2.2f, item14.mValue.float_value);
const FieldValue& item15 = event1.getValues()[15];
- EXPECT_EQ(0x2018884, item15.mField.getField());
- EXPECT_EQ(Type::FLOAT, item15.mValue.getType());
- EXPECT_EQ(1.1f, item15.mValue.float_value);
+ EXPECT_EQ(0x2018901, item15.mField.getField());
+ EXPECT_EQ(Type::INT, item15.mValue.getType());
+ EXPECT_EQ(222, item15.mValue.int_value);
+
+ const FieldValue& item16 = event1.getValues()[16];
+ EXPECT_EQ(0x2018984, item16.mField.getField());
+ EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
+ EXPECT_EQ(1.1f, item16.mValue.float_value);
}
TEST(LogEventTest, TestLogParsing2) {
@@ -292,6 +298,7 @@
EXPECT_EQ(83, event1.GetTagId());
EXPECT_EQ((int64_t)2000, event1.GetLogdTimestampNs());
EXPECT_EQ((int64_t)2001, event1.GetElapsedTimestampNs());
+ EXPECT_EQ((int64_t)10001, event1.GetUid());
const auto& items = event1.getValues();
EXPECT_EQ((size_t)17, items.size());
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index e9acdc3..d24b822 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -30,6 +30,7 @@
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.inputmethodservice.InputMethodService;
+import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -753,10 +754,20 @@
throw new IllegalStateException(e);
}
final InputMethodManager imm = new InputMethodManager(service, displayId, looper);
+ // InputMethodManagerService#addClient() relies on Binder.getCalling{Pid, Uid}() to
+ // associate PID/UID with each IME client. This means:
+ // A. if this method call will be handled as an IPC, there is no problem.
+ // B. if this method call will be handled as an in-proc method call, we need to
+ // ensure that Binder.getCalling{Pid, Uid}() return Process.my{Pid, Uid}()
+ // Either ways we can always call Binder.{clear, restore}CallingIdentity() because
+ // 1) doing so has no effect for A and 2) doing so is sufficient for B.
+ final long identity = Binder.clearCallingIdentity();
try {
service.addClient(imm.mClient, imm.mIInputContext, displayId);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
return imm;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 374c7ea..176fedb 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -400,6 +400,7 @@
<protected-broadcast android:name="android.telecom.action.DEFAULT_DIALER_CHANGED" />
<protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED" />
+ <protected-broadcast android:name="android.provider.action.SMS_MMS_DB_CREATED" />
<protected-broadcast android:name="android.intent.action.CONTENT_CHANGED" />
<protected-broadcast android:name="android.provider.Telephony.MMS_DOWNLOADED" />
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 097ce44..ba483fb 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -47,6 +47,20 @@
<dimen name="navigation_bar_height_landscape">48dp</dimen>
<!-- Width of the navigation bar when it is placed vertically on the screen -->
<dimen name="navigation_bar_width">48dp</dimen>
+
+ <!-- EXPERIMENT BEGIN -->
+ <!-- Height of the bottom navigation bar frame; this is different than navigation_bar_height
+ where that is the height reported to all the other windows to resize themselves around the
+ navigation bar window but navigation_bar_frame_height is reported to SystemUI navigation
+ bar view's window -->
+ <dimen name="navigation_bar_frame_height">@dimen/navigation_bar_height</dimen>
+ <!-- Width of the left/right navigation bar frame; this is different than navigation_bar_width
+ where that is the width reported to all the other windows to resize themselves around the
+ navigation bar window but navigation_bar_frame_width is reported to SystemUI navigation
+ bar view's window -->
+ <dimen name="navigation_bar_frame_width">@dimen/navigation_bar_width</dimen>
+ <!-- EXPERIMENT END-->
+
<!-- Height of the bottom navigation / system bar in car mode. -->
<dimen name="navigation_bar_height_car_mode">96dp</dimen>
<!-- Height of the bottom navigation bar in portrait; often the same as
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 81a1bf8..0e787cd 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1681,6 +1681,8 @@
<java-symbol type="dimen" name="navigation_bar_height" />
<java-symbol type="dimen" name="navigation_bar_height_landscape" />
<java-symbol type="dimen" name="navigation_bar_width" />
+ <java-symbol type="dimen" name="navigation_bar_frame_height" />
+ <java-symbol type="dimen" name="navigation_bar_frame_width" />
<java-symbol type="dimen" name="navigation_bar_height_car_mode" />
<java-symbol type="dimen" name="navigation_bar_height_landscape_car_mode" />
<java-symbol type="dimen" name="navigation_bar_width_car_mode" />
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/Android.mk b/packages/overlays/ExperimentNavigationBarFloatingOverlay/Android.mk
new file mode 100644
index 0000000..ee2ddc8
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := ExperimentNavigationBarFloating
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := ExperimentNavigationBarFloatingOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/AndroidManifest.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..b4b2b16
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<!--
+/**
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.internal.experiment.navbar.floating"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="com.android.internal.experiment_navbar_floating"
+ android:priority="1"/>
+
+ <application android:label="@string/experiment_navigationbar_overlay" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values/config.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values/config.xml
new file mode 100644
index 0000000..6a58453
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values/config.xml
@@ -0,0 +1,28 @@
+<?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.
+ */
+-->
+<resources>
+ <!-- Height of the bottom navigation / system bar. -->
+ <dimen name="navigation_bar_height">0dp</dimen>
+ <!-- Width of the navigation bar when it is placed vertically on the screen -->
+ <dimen name="navigation_bar_width">0dp</dimen>
+ <!-- Height of the bottom navigation / system bar frame; navigation buttons height. -->
+ <dimen name="navigation_bar_frame_height">48dp</dimen>
+ <!-- Width of the navigation bar frame when it is placed vertically on the screen -->
+ <dimen name="navigation_bar_frame_width">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values/strings.xml b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values/strings.xml
new file mode 100644
index 0000000..884846d
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarFloatingOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of overlay [CHAR LIMIT=64] -->
+ <string name="experiment_navigationbar_overlay">Floating Navigation Bar Experiment</string>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/Android.mk b/packages/overlays/ExperimentNavigationBarSlimOverlay/Android.mk
new file mode 100644
index 0000000..e642a68
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := ExperimentNavigationBarSlim
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := ExperimentNavigationBarSlimOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/AndroidManifest.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..a1bd582
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<!--
+/**
+ * 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.internal.experiment.navbar.slim"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="com.android.internal.experiment_navbar_slim"
+ android:priority="1"/>
+
+ <application android:label="@string/experiment_navigationbar_overlay" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values/config.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values/config.xml
new file mode 100644
index 0000000..4c3571a
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values/config.xml
@@ -0,0 +1,28 @@
+<?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.
+ */
+-->
+<resources>
+ <!-- Height of the bottom navigation / system bar. -->
+ <dimen name="navigation_bar_height">36dp</dimen>
+ <!-- Width of the navigation bar when it is placed vertically on the screen -->
+ <dimen name="navigation_bar_width">36dp</dimen>
+ <!-- Height of the bottom navigation / system bar frame; navigation buttons height. -->
+ <dimen name="navigation_bar_frame_width">36dp</dimen>
+ <!-- Width of the navigation bar frame when it is placed vertically on the screen -->
+ <dimen name="navigation_bar_frame_height">36dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values/strings.xml b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values/strings.xml
new file mode 100644
index 0000000..5ca9d15
--- /dev/null
+++ b/packages/overlays/ExperimentNavigationBarSlimOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of overlay [CHAR LIMIT=64] -->
+ <string name="experiment_navigationbar_overlay">Slim Navigation Bar Experiment</string>
+</resources>
\ No newline at end of file
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index e37153e..e3a1a91 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -1770,6 +1770,12 @@
@Override
public void addClient(IInputMethodClient client, IInputContext inputContext,
int selfReportedDisplayId) {
+ // Here there are two scenarios where this method is called:
+ // A. IMM is being instantiated in a different process and this is an IPC from that process
+ // B. IMM is being instantiated in the same process but Binder.clearCallingIdentity() is
+ // called in the caller side if necessary.
+ // In either case the following UID/PID should be the ones where InputMethodManager is
+ // actually running.
final int callerUid = Binder.getCallingUid();
final int callerPid = Binder.getCallingPid();
synchronized (mMethodMap) {
@@ -1778,7 +1784,7 @@
if (state.uid == callerUid && state.pid == callerPid
&& state.selfReportedDisplayId == selfReportedDisplayId) {
throw new SecurityException("uid=" + callerUid + "/pid=" + callerPid
- + " is already registered");
+ + "/displayId=" + selfReportedDisplayId + " is already registered.");
}
}
final ClientDeathRecipient deathRecipient = new ClientDeathRecipient(this, client);
diff --git a/services/core/java/com/android/server/policy/NavigationBarExperiments.java b/services/core/java/com/android/server/policy/NavigationBarExperiments.java
new file mode 100644
index 0000000..06772e3
--- /dev/null
+++ b/services/core/java/com/android/server/policy/NavigationBarExperiments.java
@@ -0,0 +1,123 @@
+/*
+ * 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.policy;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT;
+
+import android.content.Context;
+import android.graphics.Rect;
+
+import com.android.server.policy.WindowManagerPolicy.WindowState;
+import com.android.server.wm.WindowFrames;
+
+/**
+ * This class acts as a proxy for Navigation Bar experiments enabled with custom overlays
+ * {@see OverlayManagerService}. By default with no overlays, this class will essentially do nothing
+ * and pass the original resource data back. By default the navigation bar height/width is the same
+ * as the frame height/width and therefore any offsets calculated will cancel out and do nothing.
+ * TODO(b/113952590): Remove class once experiment in bug is completed
+ */
+public class NavigationBarExperiments {
+
+ private int mNavigationBarHeight;
+ private int mNavigationBarWidth;
+
+ /**
+ * This represents the height of the navigation bar buttons. With no experiments or overlays
+ * enabled, the frame height is the same as the normal navigation bar height.
+ */
+ private int mNavigationBarFrameHeight;
+
+ /**
+ * This represents the width of the navigation bar buttons. With no experiments or overlays
+ * enabled, the frame width is the same as the normal navigation bar width.
+ */
+ private int mNavigationBarFrameWidth;
+
+ /**
+ * Call when configuration change to refresh resource dimensions
+ * @param systemUiContext to get the resource values
+ */
+ public void onConfigurationChanged(Context systemUiContext) {
+ // Cache all the values again
+ mNavigationBarHeight = systemUiContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_height);
+ mNavigationBarWidth = systemUiContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_width);
+ mNavigationBarFrameHeight = systemUiContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_frame_height);
+ mNavigationBarFrameWidth = systemUiContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.navigation_bar_frame_width);
+ }
+
+ public int getNavigationBarHeight() {
+ return mNavigationBarHeight;
+ }
+
+ public int getNavigationBarWidth() {
+ return mNavigationBarWidth;
+ }
+
+ public int getNavigationBarFrameHeight() {
+ return mNavigationBarFrameHeight;
+ }
+
+ public int getNavigationBarFrameWidth() {
+ return mNavigationBarFrameWidth;
+ }
+
+ /**
+ * If navigation frame width/height is different than navigation bar width/height then only
+ * offset the ime's and home activity's window rects depending on the navigation bar position to
+ * add a gap where the navigation bar would have been drawn. With no experiments or overlays
+ * enabled, the height/width is the same as the frame height/width and the offsets calculated
+ * will be 0 and this function will do nothing.
+ * @param navPosition position of navigation bar (left, right or bottom)
+ * @param w the window that is being offset by experiment
+ */
+ public void offsetWindowFramesForNavBar(int navPosition, WindowState w) {
+ if (w.getAttrs().type != TYPE_INPUT_METHOD && w.getActivityType() != ACTIVITY_TYPE_HOME) {
+ return;
+ }
+
+ final WindowFrames windowFrames = w.getWindowFrames();
+ final Rect cf = windowFrames.mContentFrame;
+ switch (navPosition) {
+ case NAV_BAR_BOTTOM:
+ int navHeight = getNavigationBarFrameHeight() - getNavigationBarHeight();
+ if (navHeight > 0) {
+ cf.bottom -= navHeight;
+ }
+ break;
+ case NAV_BAR_LEFT:
+ case NAV_BAR_RIGHT:
+ int navWidth = getNavigationBarFrameWidth() - getNavigationBarWidth();
+ if (navWidth > 0) {
+ if (navPosition == NAV_BAR_LEFT) {
+ cf.left += navWidth;
+ } else {
+ cf.right -= navWidth;
+ }
+ }
+ break;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index c5cee32..371ac4f 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -779,6 +779,10 @@
private boolean mAodShowing;
+ // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
+ private NavigationBarExperiments mExperiments = new NavigationBarExperiments();
+ // EXPERIMENT END
+
private static final int MSG_ENABLE_POINTER_LOCATION = 1;
private static final int MSG_DISABLE_POINTER_LOCATION = 2;
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
@@ -2607,6 +2611,10 @@
res.getDimensionPixelSize(
com.android.internal.R.dimen.navigation_bar_width_car_mode);
}
+
+ // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
+ mExperiments.onConfigurationChanged(uiContext);
+ // EXPERIMENT END
}
@VisibleForTesting
@@ -4534,7 +4542,11 @@
// It's a system nav bar or a portrait screen; nav bar goes on bottom.
final int top = cutoutSafeUnrestricted.bottom
- getNavigationBarHeight(rotation, uiMode);
- navigationFrame.set(0, top, displayWidth, displayFrames.mUnrestricted.bottom);
+ // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
+ final int topNavBar = cutoutSafeUnrestricted.bottom
+ - mExperiments.getNavigationBarFrameHeight();
+ navigationFrame.set(0, topNavBar, displayWidth, displayFrames.mUnrestricted.bottom);
+ // EXPERIMENT END
displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top;
if (transientNavBarShowing) {
mNavigationBarController.setBarShowingLw(true);
@@ -4557,7 +4569,11 @@
// Landscape screen; nav bar goes to the right.
final int left = cutoutSafeUnrestricted.right
- getNavigationBarWidth(rotation, uiMode);
- navigationFrame.set(left, 0, displayFrames.mUnrestricted.right, displayHeight);
+ // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
+ final int leftNavBar = cutoutSafeUnrestricted.right
+ - mExperiments.getNavigationBarFrameWidth();
+ navigationFrame.set(leftNavBar, 0, displayFrames.mUnrestricted.right, displayHeight);
+ // EXPERIMENT END
displayFrames.mStable.right = displayFrames.mStableFullscreen.right = left;
if (transientNavBarShowing) {
mNavigationBarController.setBarShowingLw(true);
@@ -4580,7 +4596,11 @@
// Seascape screen; nav bar goes to the left.
final int right = cutoutSafeUnrestricted.left
+ getNavigationBarWidth(rotation, uiMode);
- navigationFrame.set(displayFrames.mUnrestricted.left, 0, right, displayHeight);
+ // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
+ final int rightNavBar = cutoutSafeUnrestricted.left
+ + mExperiments.getNavigationBarFrameWidth();
+ navigationFrame.set(displayFrames.mUnrestricted.left, 0, rightNavBar, displayHeight);
+ // EXPERIMENT END
displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right;
if (transientNavBarShowing) {
mNavigationBarController.setBarShowingLw(true);
@@ -4790,6 +4810,12 @@
pf.left = df.left = of.left = cf.left = vf.left = displayFrames.mStable.left;
}
}
+
+ // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
+ // Offset the ime to avoid overlapping with the nav bar
+ mExperiments.offsetWindowFramesForNavBar(mNavigationBarPosition, win);
+ // EXPERIMENT END
+
// IM dock windows always go to the bottom of the screen.
attrs.gravity = Gravity.BOTTOM;
mDockLayer = win.getSurfaceLayer();
@@ -4930,6 +4956,10 @@
} else {
vf.set(cf);
}
+
+ // EXPERIMENT TODO(b/113952590): Remove once experiment in bug is completed
+ mExperiments.offsetWindowFramesForNavBar(mNavigationBarPosition, win);
+ // EXPERIMENT END
}
} else if (layoutInScreen || (sysUiFl
& (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index db13cbc..e1c4acf 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -66,6 +66,7 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.WindowConfiguration;
import android.content.Context;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -437,6 +438,14 @@
int getWindowingMode();
/**
+ * Returns the {@link WindowConfiguration.ActivityType} associated with the configuration
+ * of this window.
+ */
+ default int getActivityType() {
+ return WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+ }
+
+ /**
* Returns true if the window is current in multi-windowing mode. i.e. it shares the
* screen with other application windows.
*/
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index d9e7167..6c9c01c 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -1245,6 +1245,33 @@
"android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL";
/**
+ * Broadcast action: When SMS-MMS db is being created. If file-based encryption is
+ * supported, this broadcast indicates creation of the db in credential-encrypted
+ * storage. A boolean is specified in {@link #EXTRA_IS_INITIAL_CREATE} to indicate if
+ * this is the initial create of the db. Requires
+ * {@link android.Manifest.permission#READ_SMS} to receive.
+ *
+ * @see #EXTRA_IS_INITIAL_CREATE
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_SMS_MMS_DB_CREATED =
+ "android.provider.action.SMS_MMS_DB_CREATED";
+
+ /**
+ * Boolean flag passed as an extra with {@link #ACTION_SMS_MMS_DB_CREATED} to indicate
+ * whether the DB creation is the initial creation on the device, that is it is after a
+ * factory-data reset or a new device. Any subsequent creations of the DB (which
+ * happens only in error scenarios) will have this flag set to false.
+ *
+ * @see #ACTION_SMS_MMS_DB_CREATED
+ *
+ * @hide
+ */
+ public static final String EXTRA_IS_INITIAL_CREATE =
+ "android.provider.extra.IS_INITIAL_CREATE";
+ /**
* Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
* {@link #DATA_SMS_RECEIVED_ACTION} intent.
*