Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab651eda authored by Shivangi Dubey's avatar Shivangi Dubey Committed by Android (Google) Code Review
Browse files

Merge "Datalayer for Desktop windowing education" into main

parents 66f164b9 a131137c
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -166,6 +166,16 @@ java_library {
    },
}

java_library {
    name: "WindowManager-Shell-lite-proto",

    srcs: ["src/com/android/wm/shell/desktopmode/education/data/proto/**/*.proto"],

    proto: {
        type: "lite",
    },
}

filegroup {
    name: "wm_shell-shared-aidls",

@@ -215,6 +225,7 @@ android_library {
        "androidx.core_core-animation",
        "androidx.core_core-ktx",
        "androidx.arch.core_core-runtime",
        "androidx.datastore_datastore",
        "androidx.compose.material3_material3",
        "androidx-constraintlayout_constraintlayout",
        "androidx.dynamicanimation_dynamicanimation",
@@ -225,6 +236,7 @@ android_library {
        "//frameworks/libs/systemui:iconloader_base",
        "com_android_wm_shell_flags_lib",
        "WindowManager-Shell-proto",
        "WindowManager-Shell-lite-proto",
        "WindowManager-Shell-shared",
        "perfetto_trace_java_protos",
        "dagger2",
+8 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ import com.android.wm.shell.desktopmode.ExitDesktopTaskTransitionHandler;
import com.android.wm.shell.desktopmode.ReturnToDragStartAnimator;
import com.android.wm.shell.desktopmode.SpringDragToDesktopTransitionHandler;
import com.android.wm.shell.desktopmode.ToggleResizeDesktopTaskTransitionHandler;
import com.android.wm.shell.desktopmode.education.data.AppHandleEducationDatastoreRepository;
import com.android.wm.shell.draganddrop.DragAndDropController;
import com.android.wm.shell.draganddrop.GlobalDragListener;
import com.android.wm.shell.freeform.FreeformComponents;
@@ -679,6 +680,13 @@ public abstract class WMShellModule {
        return new DesktopModeEventLogger();
    }

    @WMSingleton
    @Provides
    static AppHandleEducationDatastoreRepository provideAppHandleEducationDatastoreRepository(
            Context context) {
        return new AppHandleEducationDatastoreRepository(context);
    }

    //
    // Drag and drop
    //
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT 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.wm.shell.desktopmode.education.data

import android.content.Context
import android.util.Log
import androidx.datastore.core.CorruptionException
import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.Serializer
import androidx.datastore.dataStore
import androidx.datastore.dataStoreFile
import com.android.framework.protobuf.InvalidProtocolBufferException
import com.android.internal.annotations.VisibleForTesting
import java.io.InputStream
import java.io.OutputStream
import kotlinx.coroutines.flow.first

/**
 * Manages interactions with the App Handle education datastore.
 *
 * This class provides a layer of abstraction between the UI/business logic and the underlying
 * DataStore.
 */
class AppHandleEducationDatastoreRepository
@VisibleForTesting
constructor(private val dataStore: DataStore<WindowingEducationProto>) {
  constructor(
      context: Context
  ) : this(
      DataStoreFactory.create(
          serializer = WindowingEducationProtoSerializer,
          produceFile = { context.dataStoreFile(APP_HANDLE_EDUCATION_DATASTORE_FILEPATH) }))

  /**
   * Reads and returns the [WindowingEducationProto] Proto object from the DataStore. If the
   * DataStore is empty or there's an error reading, it returns the default value of Proto.
   */
  suspend fun windowingEducationProto(): WindowingEducationProto =
      try {
        dataStore.data.first()
      } catch (e: Exception) {
        Log.e(TAG, "Unable to read from datastore")
        WindowingEducationProto.getDefaultInstance()
      }

  companion object {
    private const val TAG = "AppHandleEducationDatastoreRepository"
    private const val APP_HANDLE_EDUCATION_DATASTORE_FILEPATH = "app_handle_education.pb"

    object WindowingEducationProtoSerializer : Serializer<WindowingEducationProto> {

      override val defaultValue: WindowingEducationProto =
          WindowingEducationProto.getDefaultInstance()

      override suspend fun readFrom(input: InputStream): WindowingEducationProto =
          try {
            WindowingEducationProto.parseFrom(input)
          } catch (exception: InvalidProtocolBufferException) {
            throw CorruptionException("Cannot read proto.", exception)
          }

      override suspend fun writeTo(windowingProto: WindowingEducationProto, output: OutputStream) =
          windowingProto.writeTo(output)
    }
  }
}
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

syntax = "proto2";

option java_package = "com.android.wm.shell.desktopmode.education.data";
option java_multiple_files = true;

// Desktop Windowing education data
message WindowingEducationProto {
  // Timestamp in milliseconds of when the education was last viewed.
  optional int64 education_viewed_timestamp_millis = 1;
  // Timestamp in milliseconds of when the feature was last used.
  optional int64 feature_used_timestamp_millis = 2;
  oneof education_data {
    // Fields specific to app handle education
    AppHandleEducation app_handle_education = 3;
  }

  message AppHandleEducation {
    // Map that stores app launch count for corresponding package
    map<string, int32> app_usage_stats = 1;
    // Timestamp of when app_usage_stats was last cached
    optional int64 app_usage_stats_last_update_timestamp_millis = 2;
  }
}
 No newline at end of file
+2 −0
Original line number Diff line number Diff line
@@ -44,6 +44,8 @@ android_test {
        "androidx.test.runner",
        "androidx.test.rules",
        "androidx.test.ext.junit",
        "androidx.datastore_datastore",
        "kotlinx_coroutines_test",
        "androidx.dynamicanimation_dynamicanimation",
        "dagger2",
        "frameworks-base-testutils",
Loading