Merge "support parent carrier id"
diff --git a/api/system-current.txt b/api/system-current.txt
index 6f38f1e..ed42756 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5113,6 +5113,7 @@
     method public int getDomain();
     method public int getRegState();
     method public int getRejectCause();
+    method public int getRoamingType();
     method public int getTransportType();
     method public boolean isEmergencyEnabled();
     method public boolean isRoaming();
@@ -5172,6 +5173,10 @@
     method public deprecated android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int);
     method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForDomain(int);
     method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(int);
+    field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2
+    field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3
+    field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0
+    field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1
   }
 
   public final class SmsManager {
@@ -5964,6 +5969,7 @@
     field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161
     field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160
     field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150
+    field public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157
     field public static final int CODE_SIP_USER_MARKED_UNWANTED = 365; // 0x16d
     field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169
     field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index c9edc53..7409ca7 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -917,9 +917,9 @@
         @Override
         public void close() throws IOException {
             try {
-                mPfd.close();
-            } finally {
                 super.close();
+            } finally {
+                mPfd.close();
             }
         }
 
@@ -968,9 +968,9 @@
         @Override
         public void close() throws IOException {
             try {
-                mPfd.close();
-            } finally {
                 super.close();
+            } finally {
+                mPfd.close();
             }
         }
     }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index ba72be6..325fcc6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -24045,7 +24045,7 @@
          * @param outShadowSize A {@link android.graphics.Point} containing the width and height
          * of the shadow image. Your application must set {@link android.graphics.Point#x} to the
          * desired width and must set {@link android.graphics.Point#y} to the desired height of the
-         * image.
+         * image. Since Android P, the width and height must be positive values.
          *
          * @param outShadowTouchPoint A {@link android.graphics.Point} for the position within the
          * shadow image that should be underneath the touch point during the drag and drop
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 8207a54..091c659 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1634,7 +1634,7 @@
             selectionArgs = new String[] { path };
             c = mMediaProvider.query(mFilesUriNoNotify, FILES_PRESCAN_PROJECTION,
                     where, selectionArgs, null, null);
-            if (c.moveToFirst()) {
+            if (c != null && c.moveToFirst()) {
                 long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX);
                 int format = c.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX);
                 long lastModified = c.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX);
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
new file mode 100644
index 0000000..75c0391
--- /dev/null
+++ b/packages/Shell/OWNERS
@@ -0,0 +1,10 @@
+svetoslavganov@google.com
+hackbod@google.com
+yamasani@google.com
+moltmann@google.com
+toddke@google.com
+jsharkey@google.com
+cbrubaker@google.com
+omakoto@google.com
+nandana@google.com
+felipeal@google.com
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 8cccbb1..cc11b77 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -140,13 +140,14 @@
             switch (which) {
                 case 1:
                     what1 = what;
-                    return;
+                    break;
                 case 2:
                     what2 = what;
-                    return;
+                    break;
                 default:
                     Slog.w(TAG, "Can't set unsupported disable flag " + which
                             + ": 0x" + Integer.toHexString(what));
+                    break;
             }
             this.pkg = pkg;
         }
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 13e7f73..33df6f9 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -17,7 +17,6 @@
 #include "dex_builder.h"
 
 #include "dex/descriptors_names.h"
-#include "dex/dex_instruction.h"
 
 #include <fstream>
 #include <memory>
@@ -56,6 +55,12 @@
     case Instruction::Op::kInvokeVirtual:
       out << "kInvokeVirtual";
       return out;
+    case Instruction::Op::kBindLabel:
+      out << "kBindLabel";
+      return out;
+    case Instruction::Op::kBranchEqz:
+      out << "kBranchEqz";
+      return out;
   }
 }
 
@@ -224,6 +229,11 @@
 
 Value MethodBuilder::MakeRegister() { return Value::Local(num_registers_++); }
 
+Value MethodBuilder::MakeLabel() {
+  labels_.push_back({});
+  return Value::Label(labels_.size() - 1);
+}
+
 void MethodBuilder::AddInstruction(Instruction instruction) {
   instructions_.push_back(instruction);
 }
@@ -254,6 +264,10 @@
       return EncodeMove(instruction);
     case Instruction::Op::kInvokeVirtual:
       return EncodeInvokeVirtual(instruction);
+    case Instruction::Op::kBindLabel:
+      return BindLabel(instruction.args()[0]);
+    case Instruction::Op::kBranchEqz:
+      return EncodeBranch(art::Instruction::IF_EQZ, instruction);
   }
 }
 
@@ -307,7 +321,22 @@
   }
 }
 
-size_t MethodBuilder::RegisterValue(Value value) const {
+// Encodes a conditional branch that tests a single argument.
+void MethodBuilder::EncodeBranch(art::Instruction::Code op, const Instruction& instruction) {
+  const auto& args = instruction.args();
+  const auto& test_value = args[0];
+  const auto& branch_target = args[1];
+  CHECK_EQ(2, args.size());
+  CHECK(test_value.is_variable());
+  CHECK(branch_target.is_label());
+
+  size_t instruction_offset = buffer_.size();
+  buffer_.push_back(op | (RegisterValue(test_value) << 8));
+  size_t field_offset = buffer_.size();
+  buffer_.push_back(LabelValue(branch_target, instruction_offset, field_offset));
+}
+
+size_t MethodBuilder::RegisterValue(const Value& value) const {
   if (value.is_register()) {
     return value.value();
   } else if (value.is_parameter()) {
@@ -317,6 +346,37 @@
   return 0;
 }
 
+void MethodBuilder::BindLabel(const Value& label_id) {
+  CHECK(label_id.is_label());
+
+  LabelData& label = labels_[label_id.value()];
+  CHECK(!label.bound_address.has_value());
+
+  label.bound_address = buffer_.size();
+
+  // patch any forward references to this label.
+  for (const auto& ref : label.references) {
+    buffer_[ref.field_offset] = *label.bound_address - ref.instruction_offset;
+  }
+  // No point keeping these around anymore.
+  label.references.clear();
+}
+
+::dex::u2 MethodBuilder::LabelValue(const Value& label_id, size_t instruction_offset,
+                                    size_t field_offset) {
+  CHECK(label_id.is_label());
+  LabelData& label = labels_[label_id.value()];
+
+  // Short-circuit if the label is already bound.
+  if (label.bound_address.has_value()) {
+    return *label.bound_address - instruction_offset;
+  }
+
+  // Otherwise, save a reference to where we need to back-patch later.
+  label.references.push_front(LabelReference{instruction_offset, field_offset});
+  return 0;
+}
+
 const MethodDeclData& DexBuilder::GetOrDeclareMethod(TypeDescriptor type, const std::string& name,
                                                      Prototype prototype) {
   MethodDeclData& entry = method_id_map_[{type, name, prototype}];
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h
index e46655e..0744151 100644
--- a/startop/view_compiler/dex_builder.h
+++ b/startop/view_compiler/dex_builder.h
@@ -16,12 +16,14 @@
 #ifndef DEX_BUILDER_H_
 #define DEX_BUILDER_H_
 
+#include <forward_list>
 #include <map>
 #include <optional>
 #include <string>
 #include <unordered_map>
 #include <vector>
 
+#include "dex/dex_instruction.h"
 #include "slicer/dex_ir.h"
 #include "slicer/writer.h"
 
@@ -108,15 +110,18 @@
   static constexpr Value Local(size_t id) { return Value{id, Kind::kLocalRegister}; }
   static constexpr Value Parameter(size_t id) { return Value{id, Kind::kParameter}; }
   static constexpr Value Immediate(size_t value) { return Value{value, Kind::kImmediate}; }
+  static constexpr Value Label(size_t id) { return Value{id, Kind::kLabel}; }
 
   bool is_register() const { return kind_ == Kind::kLocalRegister; }
   bool is_parameter() const { return kind_ == Kind::kParameter; }
+  bool is_variable() const { return is_register() || is_parameter(); }
   bool is_immediate() const { return kind_ == Kind::kImmediate; }
+  bool is_label() const { return kind_ == Kind::kLabel; }
 
   size_t value() const { return value_; }
 
  private:
-  enum class Kind { kLocalRegister, kParameter, kImmediate };
+  enum class Kind { kLocalRegister, kParameter, kImmediate, kLabel };
 
   const size_t value_;
   const Kind kind_;
@@ -132,7 +137,7 @@
  public:
   // The operation performed by this instruction. These are virtual instructions that do not
   // correspond exactly to DEX instructions.
-  enum class Op { kReturn, kMove, kInvokeVirtual };
+  enum class Op { kReturn, kMove, kInvokeVirtual, kBindLabel, kBranchEqz };
 
   ////////////////////////
   // Named Constructors //
@@ -195,6 +200,8 @@
   // it's up to the caller to reuse registers as appropriate.
   Value MakeRegister();
 
+  Value MakeLabel();
+
   /////////////////////////////////
   // Instruction builder methods //
   /////////////////////////////////
@@ -215,9 +222,18 @@
   void EncodeReturn(const Instruction& instruction);
   void EncodeMove(const Instruction& instruction);
   void EncodeInvokeVirtual(const Instruction& instruction);
+  void EncodeBranch(art::Instruction::Code op, const Instruction& instruction);
 
   // Converts a register or parameter to its DEX register number.
-  size_t RegisterValue(Value value) const;
+  size_t RegisterValue(const Value& value) const;
+
+  // Sets a label's address to the current position in the instruction buffer. If there are any
+  // forward references to the label, this function will back-patch them.
+  void BindLabel(const Value& label);
+
+  // Returns the offset of the label relative to the given instruction offset. If the label is not
+  // bound, a reference will be saved and it will automatically be patched when the label is bound.
+  ::dex::u2 LabelValue(const Value& label, size_t instruction_offset, size_t field_offset);
 
   DexBuilder* dex_;
   ir::Class* class_;
@@ -231,6 +247,21 @@
 
   // How many registers we've allocated
   size_t num_registers_{0};
+
+  // Stores information needed to back-patch a label once it is bound. We need to know the start of
+  // the instruction that refers to the label, and the offset to where the actual label value should
+  // go.
+  struct LabelReference {
+    size_t instruction_offset;
+    size_t field_offset;
+  };
+
+  struct LabelData {
+    std::optional<size_t> bound_address;
+    std::forward_list<LabelReference> references;
+  };
+
+  std::vector<LabelData> labels_;
 };
 
 // A helper to build class definitions.
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
index 87b2578..169c633 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -65,4 +65,21 @@
     Method method = clazz.getMethod("returnStringLength", String.class);
     Assert.assertEquals(13, method.invoke(null, "Hello, World!"));
   }
+
+  @Test
+  public void returnIfZero() throws Exception {
+    ClassLoader loader = loadDexFile("simple.dex");
+    Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+    Method method = clazz.getMethod("returnIfZero", int.class);
+    Assert.assertEquals(5, method.invoke(null, 0));
+    Assert.assertEquals(3, method.invoke(null, 17));
+  }
+
+  @Test
+  public void backwardsBranch() throws Exception {
+    ClassLoader loader = loadDexFile("simple.dex");
+    Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+    Method method = clazz.getMethod("backwardsBranch");
+    Assert.assertEquals(2, method.invoke(null));
+  }
 }
diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc
index 898817b..c521bf2 100644
--- a/startop/view_compiler/dex_testcase_generator.cc
+++ b/startop/view_compiler/dex_testcase_generator.cc
@@ -46,9 +46,11 @@
 
   // int return5() { return 5; }
   auto return5{cbuilder.CreateMethod("return5", Prototype{TypeDescriptor::Int()})};
-  Value r{return5.MakeRegister()};
-  return5.BuildConst4(r, 5);
-  return5.BuildReturn(r);
+  {
+    Value r{return5.MakeRegister()};
+    return5.BuildConst4(r, 5);
+    return5.BuildReturn(r);
+  }
   return5.Encode();
 
   // // int returnParam(int x) { return x; }
@@ -64,12 +66,78 @@
 
   auto returnStringLength{
       cbuilder.CreateMethod("returnStringLength", Prototype{TypeDescriptor::Int(), string_type})};
-  Value result = returnStringLength.MakeRegister();
-  returnStringLength.AddInstruction(
-      Instruction::InvokeVirtual(string_length.id, result, Value::Parameter(0)));
-  returnStringLength.BuildReturn(result);
+  {
+    Value result = returnStringLength.MakeRegister();
+    returnStringLength.AddInstruction(
+        Instruction::InvokeVirtual(string_length.id, result, Value::Parameter(0)));
+    returnStringLength.BuildReturn(result);
+  }
   returnStringLength.Encode();
 
+  // int returnIfZero(int x) { if (x == 0) { return 5; } else { return 3; } }
+  MethodBuilder returnIfZero{cbuilder.CreateMethod(
+      "returnIfZero", Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})};
+  {
+    Value resultIfZero{returnIfZero.MakeRegister()};
+    Value else_target{returnIfZero.MakeLabel()};
+    returnIfZero.AddInstruction(Instruction::OpWithArgs(
+        Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target));
+    // else branch
+    returnIfZero.BuildConst4(resultIfZero, 3);
+    returnIfZero.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfZero));
+    // then branch
+    returnIfZero.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, else_target));
+    returnIfZero.BuildConst4(resultIfZero, 5);
+    returnIfZero.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfZero));
+  }
+  returnIfZero.Encode();
+
+  // Make sure backwards branches work too.
+  //
+  // Pseudo code for test:
+  // {
+  //   zero = 0;
+  //   result = 1;
+  //   if (zero == 0) goto B;
+  // A:
+  //   return result;
+  // B:
+  //   result = 2;
+  //   if (zero == 0) goto A;
+  //   result = 3;
+  //   return result;
+  // }
+  // If it runs correctly, this test should return 2.
+  MethodBuilder backwardsBranch{
+      cbuilder.CreateMethod("backwardsBranch", Prototype{TypeDescriptor::Int()})};
+  [](MethodBuilder& method) {
+    Value zero = method.MakeRegister();
+    Value result = method.MakeRegister();
+    Value labelA = method.MakeLabel();
+    Value labelB = method.MakeLabel();
+    method.BuildConst4(zero, 0);
+    method.BuildConst4(result, 1);
+    method.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kBranchEqz, /*dest=*/{}, zero, labelB));
+
+    method.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, labelA));
+    method.BuildReturn(result);
+
+    method.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, labelB));
+    method.BuildConst4(result, 2);
+    method.AddInstruction(
+        Instruction::OpWithArgs(Instruction::Op::kBranchEqz, /*dest=*/{}, zero, labelA));
+
+    method.BuildConst4(result, 3);
+    method.BuildReturn(result);
+  }(backwardsBranch);
+  backwardsBranch.Encode();
+
   slicer::MemView image{dex_file.CreateImage()};
   std::ofstream out_file(outdir + "/simple.dex");
   out_file.write(image.ptr<const char>(), image.size());
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index c3d8898..68e512e 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -237,10 +237,9 @@
     }
 
     /**
-     * @return {@link ServiceState.RoamingType roaming type}. This could return
-     * overridden roaming type based on resource overlay or carrier config.
-     * @hide
+     * @return the current network roaming type.
      */
+
     public @ServiceState.RoamingType int getRoamingType() {
         return mRoamingType;
     }
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index 46e2adb..2acaf34 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -332,6 +332,8 @@
     public static final int SIP_NOT_REACHABLE                                = 1320;
     /** Others */
     public static final int SIP_CLIENT_ERROR                                 = 1321;
+    /** 481 : Transaction Does Not Exist */
+    public static final int SIP_TRANSACTION_DOES_NOT_EXIST                   = 1322;
     /** 5xx responses
      *  501 : Server Internal Error
      */
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index c407681..0937b10 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -211,29 +211,30 @@
             ROAMING_TYPE_INTERNATIONAL
     })
     public @interface RoamingType {}
+
     /**
-     * Roaming type
-     * HOME : in home network
+     * Not roaming, registered in home network.
      * @hide
      */
+    @SystemApi
     public static final int ROAMING_TYPE_NOT_ROAMING = 0;
     /**
-     * Roaming type
-     * UNKNOWN : in a roaming network, but we can not tell if it's domestic or international
+     * registered in a roaming network, but can not tell if it's domestic or international.
      * @hide
      */
+    @SystemApi
     public static final int ROAMING_TYPE_UNKNOWN = 1;
     /**
-     * Roaming type
-     * DOMESTIC : in domestic roaming network
+     * registered in a domestic roaming network
      * @hide
      */
+    @SystemApi
     public static final int ROAMING_TYPE_DOMESTIC = 2;
     /**
-     * Roaming type
-     * INTERNATIONAL : in international roaming network
+     * registered in an international roaming network
      * @hide
      */
+    @SystemApi
     public static final int ROAMING_TYPE_INTERNATIONAL = 3;
 
     /**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index fe7935e..016a77d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -9203,7 +9203,7 @@
     public static final int NETWORK_TYPE_BITMASK_LTE_CA = (1 << NETWORK_TYPE_LTE_CA);
 
     /**
-     * @return Modem supported radio access family bitmask {@link NetworkTypeBitMask}
+     * @return Modem supported radio access family bitmask
      *
      * <p>Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
      * that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index c976666..8fcdb6e 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -164,6 +164,8 @@
     public static final int CODE_SIP_NOT_REACHABLE = 341;
     // Others
     public static final int CODE_SIP_CLIENT_ERROR = 342;
+    // 481 Transaction Does Not Exist
+    public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343;
     // 5xx responses
     // 501 : Server Internal Error
     public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351;